I wanted a December tradition: a free digital advent calendar for friends, with a small puzzle behind every door. Not chocolate, not a prize draw, just a riddle, a cipher or a bit of code to work out each morning. Solving a door gives you a word. Collect every word and they form the key to a completion certificate with your name on it.

Advent is the engine that runs it. You write the puzzles, seal them, and it publishes a static site that opens one door a day.

My own calendar is live at advent.4sh.dev with two editions for this year: one for kids aged 5 to 8, and one for grown-ups. Both open on December 1st.

The landing page of my calendar: one card per edition, each with its own artwork and a countdown to the first door.

The landing page of my calendar: one card per edition, each with its own artwork and a countdown to the first door.

What players see

A calendar is a grid of doors. Each door is locked until its date, then open, then solved. Above the grid sits your key: one slot per day, filling in with words as you go.

The 24-door Christmas showcase. Ten doors are open, the rest show the date they open on. The key strip at the top is still empty.

The 24-door Christmas showcase. Ten doors are open, the rest show the date they open on. The key strip at the top is still empty.

Opening a door shows the puzzle and an answer box. Puzzles come in a few kinds: teasers, code puzzles, ciphers, logic and image puzzles, trivia, and a meta puzzle that uses earlier answers. Hints unlock on their own schedule after the door opens, so someone who is stuck doesn’t stay stuck for long.

Day 2 of the Christmas showcase: a small cipher, an answer box and two hints waiting.

Day 2 of the Christmas showcase: a small cipher, an answer box and two hints waiting.

When the last word is in, you type the name that goes on the certificate and it opens in the browser. You can print it (it fills a landscape page, A4 or US Letter) or download it as a PNG. The idea came from the medals and certificates of virtual challenges: not a big prize, but something to show you went all the way.

The certificate from the seven-door demo, unlocked by the words of every door.

The certificate from the seven-door demo, unlocked by the words of every door.

The certificate doesn’t have to be the only reward. A calendar can also unlock downloads and links that appear under the certificate once it opens: a coloring book to print for the holidays, a few games for the kids, a wallpaper pack, a bonus puzzle. Like everything else, those files are encrypted, so they can’t be grabbed early from the published site, and they’re only downloaded when the player asks for them. Everyone who finishes gets the same rewards, so it suits gifts like these rather than one-off codes.

Progress lives in the player’s browser. A “move your progress” panel gives a short code to carry it to another device.

Nothing leaks early

The part I cared most about was that nobody, including me, can peek. A calendar where you can open December 24th on December 1st by reading the page source is not much of a calendar.

So puzzles are never committed in plain text. Each day is written as a small folder (the puzzle in Markdown, plus the answers, the word and the hints), and the engine seals it before it goes into git. A sealed day can only be opened with a release key that lives in the CI secrets. Every night after midnight, a scheduled job builds the site with whatever days are due and deploys it. Days that aren’t due yet simply aren’t in the published site.

Answers don’t ship either. The site only carries a lock for each day’s word, and the player’s answer is what opens it, right in the browser. A wrong answer opens nothing, and there is no list of correct answers to find. The certificate works the same way: it is encrypted with a key built from all the words in order, so the only way to read it is to have solved every door.

My first sketch had a tiny worker gating each day by date. Building the site on a schedule turned out simpler: no server, no database, and any static host can serve it.

Your calendar, your brand

The engine is one binary. Your calendar lives in its own private repository that pins an engine version and holds your brand (name, logo, light and dark palettes), a theme for each year, and every year’s events. Days can be consecutive, every few days, workdays only, or on chosen dates.

Several people can write puzzles together. An editors key lets authors reopen and edit any day, and an author who wants to stay surprised can skip that key and still seal their own days.

There is also a company edition for when a static site isn’t enough: the same calendar, but for invited players only, with sign-in links by email, answers checked on a server, and an admin section to invite players, follow each day’s completion and export the people who finished. It ships as a Docker image.

Try it

The demo has seven sample doors, all open, certificate included. The gallery shows a branded company calendar and a full 24-day Christmas one.

To build your own, the docs walk through writing a day, sealing it and deploying, and the code is on GitHub.

The engine is done enough for this year. The real work now is the puzzles, before December 1st.