Skip to main content

Your Club, Your Product Types

· 4 min read
Dave Rapin
Dave Rapin
Founder @ Curling IO

Curling clubs sell much more than leagues and bonspiels. They run clinics, rent ice, assign lockers, host junior camps, sell banquet tables, and collect donations.

Today, each of those offerings has to fit one of Curling IO's predefined types. That works, but sometimes only because a club picks the closest available bucket. One active junior summer camp is stored as a Product, with its August dates written into the name. A full-sheet ice rental is stored as a Program because it needs a date, capacity, and a waitlist. A donation is stored as a Fee.

In Curling IO v3, the organization decides which product types it needs. A club can create Camps, Clinics, Ice Rentals, Locker Rentals, Fundraising, or any other category that fits its operation, then choose what each type can do.

Why Your Curling Club Shouldn't Use a CMS

· 9 min read
Dave Rapin
Dave Rapin
Founder @ Curling IO

We know that many of our clubs use WordPress or Joomla for their curling websites. These are popular platforms, and for good reason: they're flexible and there's no shortage of tutorials and plugins. But that popularity comes with a serious downside. General-purpose CMS platforms are big targets, and volunteer-run clubs often don't have anyone watching the security queue. Here's what you need to know.

Automate Club Management With AI

· 5 min read
Dave Rapin
Dave Rapin
Founder @ Curling IO

Imagine you're a club manager setting up next season. You open your AI agent and type (or just say):

Set up early bird pricing for the Tuesday Night League. 15% off if they register before September 1st.

Five seconds later, it's done. No browser tabs, no forms, no clicking through menus. With Curling IO v3, this is something you'll be able to do.

Custom Registration Forms Are Coming to Curling IO

· 3 min read
Dave Rapin
Dave Rapin
Founder @ Curling IO

Registration forms in Curling IO have always collected the basics: team name, lineup, skill level, contact info. But every club runs things a little differently. Some need emergency contacts. Others want dietary restrictions for banquet planning. A bonspiel might ask for team contact information while a league doesn't.

In v2, admins can already choose which questions appear and create custom ones. What's new in v3 is control over the layout: where each question sits, how wide it is, and how the form is organized into sections.

Live Admin With Gleam and Lustre

· 11 min read
Dave Rapin
Dave Rapin
Founder @ Curling IO

Curling IO's admin panel should feel instant when a club manager is working through a season setup. Toggle a setting, save a discount, move between product sections: the page should respond without a full reload.

Version 2 works, but every form submission reloads the page. Version 3's admin is a single Lustre server component running on the BEAM. One WebSocket connection, one long-lived Erlang process per session. Every interaction goes over that WebSocket and comes back as a DOM patch. The page never reloads, and there's no client-side JavaScript framework.

AI Agents Love Gleam

· 12 min read
Dave Rapin
Dave Rapin
Founder @ Curling IO

Fair warning: this post contains some opinions that are going to be controversial and may not age well. Here be dragons.

AI coding agents like Claude Code, OpenAI Codex, and Google Gemini can write code, run it, read the errors, and try again. That loop is the whole game. The faster and more informative that loop is, the more useful the agent becomes. After building Curling IO Version 3 in Gleam alongside AI coding agents, I'm convinced Gleam is the best language for this workflow. Agents don't write better Gleam - there's less training data. But Gleam's compiler lets agents self-correct without waiting for a human.

Parallel Tests for Free

· 5 min read
Dave Rapin
Dave Rapin
Founder @ Curling IO

While writing the previous post about our per-test SQLite databases, I was describing how each test gets its own in-memory database, no shared connections, no shared state. And I thought: wait, if nothing is shared, can we just run them all at the same time?

Turns out we could, and our server test suite went from ~4 seconds to ~0.85 seconds for around 800 tests. Zero code changes to the tests themselves. One 25-line Erlang module.

Test Isolation for Free with SQLite

· 9 min read
Dave Rapin
Dave Rapin
Founder @ Curling IO

Curling IO's tests don't need a shared test database, cleanup hooks, or transaction tricks. Each test gets its own database, so a test can pass alone or in the full suite for the same reason: nothing else can touch its data.

That falls out of one Version 3 choice: SQLite runs in-process. Each test gets a completely independent in-memory SQLite database, cloned from a template in microseconds using SQLite's backup API.