SvelteKit (SvelteJS 5) + Supabase + Vercel
Table of Contents
the problem
I regularly attend volleyball tournaments hosted around the Buffalo area. These events are always a great deal of fun, and we are fortunate to have venues and individuals willing to organize them.
That being said, creating a balanced “round robin” schedule and keeping teams on schedule often requires significant effort. The difficulties associated with creating these schedules will be discussed below.
In short, the schedules are usually handmade, and teams frequently end up playing consecutive games in a row or sitting idle for too long, resulting in grumbling and general dissatisfaction.
the format
Typically, tournaments follow this format:
- Play X games of
pool
play — This is for seeding before going into playoffs. - During pool play, teams are expected to ref other teams’ matches (this means refs need to be pulled from teams not playing). But it is considered bad practice to play a game, ref and then play again with no ‘downtime’ between.
- Teams should ref the same amount of games where possible.
- Teams should sit in between games logical amounts.
the challenges
The main issues with creating a schedule by hand are that teams often end up playing multiple games in a row or sitting for too long.
Just recently I was at a tournament that had three sand courts available for use, the schedule has been planned out ahead of time to optimally use these courts for ten teams. Then day of the event, 15 minutes before start time, an 11th team showed up. While we were able to get a pre-fabricated 11 team round robin schedule from online, we couldn’t balance the schedule in a way that would allow us to utilize all three courts. There was general chaos around managing the schedule that day.
Compounding these difficulties, there are often only a few copies of the schedule available, whether due to last-minute changes or a lack of physical copies. This means that a central schedule is typically taped up for participants to view, leading to teams often being slow to realize when they should be on the court or, even more so, when they should be refereeing.
I knew I wanted to build something fun and educational using my favorite tech stack (SvelteKit and Supabase). This is the problem I chose to tackle, even though I realize that scheduling tournaments is a problem that has already been solved in many ways.
the tech
vercel
“Vercel provides the developer tools and cloud infrastructure to build, scale, and secure a faster, more personalized web.”
Vercel is an amazing product and a logical choice for deploying my SvelteKit infrastructure. By utilizing the Vercel adapter for SvelteKit. Getting my application up and running in the cloud only took minutes. By using Vercel, I had easy access to logs, and I find it much more simple than using the AWS console! Deployments for branches and PRs are automatically generated and reviewable.
supabase
Another product that has truly impressed me!
“Supabase is an open-source Firebase alternative. Start your project with a Postgres database, Authentication, instant APIs, Edge Functions, Realtime subscriptions, Storage, and Vector embeddings.”
Supabase has made things such as Auth and real-time functionality a piece of cake! Supabase handles user Auth and email (amongst other Auth/Notification methods) but also makes developing a dream. Typically creating and managing a local test DB can be a pain, and I truly dislike when engineering teams all use one dev cloud test DB (you never know how messed up the DB state is).
Supabase makes it easy to spin up a local Supabase web studio along with a database instance to allow for easy and effective DB testing and version control!
svelte 5 and sveltekit
Svelte is amazing, and working with Svelte 5 has felt really good! Switching to runes was actually very straightforward and along the way I feel I’ve learned some better practices as far as reactivity in the frontend goes.
The results
A reactive frontend
When logged in as an admin user, several CRUD options are available, such as managing Settings, Teams, and Matches, with Brackets coming soon.
I aimed to make the UI as modern and responsive as possible. By using Superforms’ use:enhance
, form submissions no longer trigger a page reload, making updates to Event values feel seamless and fast. However, this introduced a challenge: What happens when the UI loads and mounts components?
For instance, on initial page load, I load TypeScript objects for a specific event ID and use prop drilling to pass the Event (settings), Teams, and Matches class instances to various components. But if one component updates one of these class instances, other components that depend on the same data must also be aware of these changes.
For example, if I’ve generated Matches for pool play and the UI displays them on an already mounted component, what happens if I change a team name on the Teams tab? Naturally, I’d want the Matches tab to reactively update and display the new team name across all relevant matches.
To handle this, I used the following Svelte 5 syntax in our +page.svelte route:

We need attributes on our Teams
class to be stateful:

So we use the $state
feature in Svelte 5 (instead of team.ts
as the file name it is now teams.svelte.ts
)!
This means that the UI can now be reactive to when the teams
attribute on a Teams class instance changes! (It does mean we are using a proxy value which can cause issues in other places if you want the values. Can use $state.snapshot
)
So now when I render a match instead of reloading all my matches that contain the updated team I can do something like this:

Where if we update our Team value it will reactively update the matches component UI!
realtime updates
One of the features I was excited to try out from Supabase was the easy real-time updates that the JS SDK could subscribe to. With a little bit of code:

Realtime updates are displayed on the matches
tab:
I could easily have my Svelte components update in real-time when match results were input. This means when an event organizer puts results in, users who have the event open on their mobile devices will get the update pushed straight to their UI without a page refresh.
demo

conclusion
Building a scheduling tool for volleyball tournaments using SvelteKit and Supabase has been a fun and educational experience. At the time of writing this I will be piloting the app for a tournament this coming weekend, so hopefully disaster does not ensue!
P.S
I am currently looking for my next career opportunity, so if anyone knows of anyone hiring for Svelte or similar positions, please let me know!
Thanks for reading!