Back to Projects

Guess The Word

Node.js
Postgres
Svelte
Tailwind
WebSocket

A real-time multiplayer word guessing game

Overview

Guess The Word is a real-time multiplayer word guessing game where players take turns guessing a word until they come to an agreement.

Features

Tech Stack

SvelteKit & Svelte

Svelte is a new rendering library that was created at The Guardian and was ranked as the most admired web framework in Stack Overflow’s 2024 Developer Survey.

SvelteKit is the server-side part of Svelte that enables Server Side Rendering, REST APIs, etc.

Svelte is part of a new breed of web frameworks that compile component source code down into JavaScript, instead of being a pure JavaScript library. Svelte’s popularity is why React is introducing the React Compiler.

Being a web framework in the 2020s, Svelte is also keenly aware of the need for Server Side Rendering and its interplay with Client Side Rendering. SvelteKit very explicitly models where data loading is happening: server-only, client-only, or both. This explicit modeling of the data loading lifecycle introduces some interesting problems.

I had a lot of trouble understanding how to perform authentication, because knowing where to store the JWT token and when to trust it were mental models I didn’t have before. In the end, I went with server hooks, storing the auth details in locals, then performing server-side loading of a user’s credentials every time they navigate to a page that needs authentication. I couldn’t trust the JWT token in the Authorization header handed to me from the client-side, because the client could have modified it. The Lucia guide was incredibly helpful in understanding how to set up authentication.

WebSockets

Socket.io is the WebSockets implementation of choice for this project.

Originally I wanted to use Spring’s STOMP support with a Kotlin backend. Unfortunately, the STOMP.js library isn’t really well-known in the JavaScript ecosystem; this is probably a reflection of how STOMP is mostly a messaging middleware integration, and that usually happens in the backend. I also got tired of having to duplicate the message object models on both Kotlin and JavaScript sides, and other constraints in this project compelled me to look for a pure JavaScript solution. You can still find the original Kotlin backend here.

Node.js & Express.js

An Express.js server in the backend provides:

The server talks to Supabase, an open-source Firebase alternative. Supabase allowed me to use standard Postgres instead of proprietary constructs only available in Firebase.

Games are created by making an entry in the Games table, and only events from authenticated users can trigger the server to create it. After a game ends, the entry is deleted.

Originally, the plan was to store finished games and then run some kind of analytics on them. I quickly realized that not enough people would be playing the game, so any kind of analytics generated would be overkill. Maybe one day I’ll get around to it.