-- views

How I use Zod with Wordle Unlimited

February 25, 2024

When dealing with data that goes over the network or stored in localeStorage or any other place where we don't have full control over it

Let's say we built a strictly typed way to store data in localStorage.

type Colors = 'red' | 'green' | 'blue';
const key = 'colors';
const data: Colors[] = ['green', 'red'];
localStorage.setItem(key, JSON.stringify(data));

Since we have no control over what happens to the data, it is outside of our type system. A user might go into their developer tools and alter the data

at this point, our data went outside of the type system and now there is no guarantee that the data still satisfies the Colors type.

What we have done now, is having types and it is not the same as having type safety!

A quick intro into ZOD#

Zod is used for data validation in TypeScript applications.

The primary goal is to enforce precise data structures, ensuring that incoming data conforms to expected types and shapes. For more information refer to How to validate data using Zod

A quick intro to Wordle Unlimited#

Wordle Unlimited is a guessing game consisting of 6 tries after each guess the color of the tiles will change to how close your guess was to the word. Each guess must be a valid word with the same number of letters as the number of squares horizontally



We aim to save the game progress in the browser localeStorage while ensuring type checks on stored values. This will play a role in safeguards against potential game-breaking issues if values are altered.

Validation with Zod#

The schema represents the structure and validation rules for the Wordle data type

export const GameSchema = z.object({
	currentGuess: z.string(),
	isWon: z.boolean(),
	isLost: z.boolean(),
	invalidGuess: z.boolean(),
	guesses: z.array(z.array(z.string())),
	solution: z.string(),

To void code duplication we can extract the TypeScript type of GameSchema using z.infer

type GameState = z.infer<typeof GameSchema>;

Now to get the data back we can use safeParse. This method returns an object containing either the successfully parsed data or a ZodError instance containing detailed information about the validation

const data = localStorage.getItem(WORDLE_LOCAL_STORAGE_KEY);
const results = GameSchema.safeParse(data);
if (!results.success) {
    // initialize the game with the default state
} else {
    // initialize the game with successfully parsed data ""

This way enables us to utilize ZOD for validating external data that falls outside our type system.


Let’s work together

I build exceptional and accessible digital experiences for the web