Inspiration
Wordle proved that one small puzzle a day, shared by everyone and finished in about a minute, can quietly become a habit. I wanted that same one-a-day rhythm pointed at a different kind of puzzle: the word ladder, an old idea that Lewis Carroll wrote about in 1877 and called Doublets. You connect two words by changing a single letter at a time, keeping a real word at every step.
The other half of the inspiration was a reaction to friction. My favorite daily games kept asking for an account, hiding the puzzle under newsletters, or taking longer than the coffee did. I wanted the opposite: a page that loads instantly, explains itself in one sentence, needs no login, and is done in under a minute. Fixing the destination at POOP gave the game a friendly, memorable name and a single target every player can plan around.
What it does
Poople is a daily four letter word ladder. Everyone in the world gets the same starting word each day, and you change one letter at a time until you reach POOP. Every rung has to be a valid four letter word, and the fewer steps you take, the better you score against par, which is the shortest possible path for that day. When you finish, you can copy a spoiler free grid to share, in the same spirit as the Wordle share.
It runs entirely in the browser, it is free, and it needs no account. Your wins, best streak, and average steps live in your own browser. There are three ways to play plus two helper pages:
- Daily: the shared puzzle, refreshed every morning at 08:00 UTC.
- Unlimited: a free practice mode with a fresh random starting word on demand, which never touches your daily streak.
- Answers: an archive where each past puzzle publishes its verified shortest path, progressive hints, and short definitions for the bridge words.
- Word Ladder Solver: type any two four letter words and it finds the shortest ladder between them, along with every path of the same length.
- FAQ: a help center that explains the rules, scoring, and strategy.
How I built it
The whole game is built on one idea: the date is the only shared state it needs. If today's puzzle is a pure function of the current date, then every browser computes the same puzzle on its own and no server has to choose it. I count whole days since a fixed epoch, and that single integer is both the puzzle number and the index into a list of starting words. Open the page in New York, London, or Tokyo at the same moment and you all get the same word.
The stack is Next.js 15 with the App Router, deployed to Cloudflare through OpenNext. Data lives in Cloudflare D1, which is SQLite, with Drizzle ORM on top, and the runtime leans on Cloudflare Workers, Durable Objects, KV, and R2. Copy and translations go through next-intl, and the UI is Tailwind CSS.
The Word Ladder Solver reuses that same graph search on the client. It runs a multi parent breadth first search that enumerates every equal length shortest path between two words, capped so a highly connected word cannot explode the result.
Challenges I ran into
Time zones were the first trap. If you key the puzzle off local time, players in different zones get different puzzles and the shared promise breaks. The fix was to keep every comparison in UTC and bake an 08:00 UTC offset straight into the epoch, so the day flips at the same instant for everyone and the rest of the math stays a plain division. That removes the off by one that bites most people the first time.
Server rendering was the second. Because the daily word is deterministic, the server and client compute the same value and there is no hydration mismatch. The practice mode wanted a random word instead, and calling Math.random during render made the server and client disagree. I had to treat the random pick as a client only effect so the first paint stays stable.
Scoring had to handle the fact that a puzzle often has several shortest paths of the same length. Scoring by step count against the BFS par makes every optimal route a top result, so multiple valid answers are fine and expected.
There was also an operational scare. One morning the Cloudflare cron simply did not fire, and the daily answer never published. I built a guarded self heal endpoint that checks whether the scheduled run was missed and the ledger is behind, and only then republishes by hand, with the same idempotent job the cron uses.
Finally, the new solver created a spoiler risk: if someone typed today's starting word and aimed at POOP, it would hand them the day's answer. So the solver detects today's daily pair in either direction and politely refuses, pointing players to the daily puzzle or to Unlimited instead.
Accomplishments that I'm proud of
The biggest one is that a daily game with streaks, an archive, and a solver turned out to need no backend at all. It is static assets on a CDN plus a little localStorage, so there are no cold starts, no database to scale, and the hosting cost rounds down to nothing.
What I learned
The headline lesson is that the date was all the shared state the game actually needed. Once the puzzle is a pure function of time and player state stays on the device, the server I was about to build turned out to be optional. Determinism also keeps server rendering boring in the best possible way, as long as you isolate any randomness to a client only effect.
I learned to name the tradeoffs of a client authoritative design out loud: you give up server authority and cross device sync, which is fine for a casual daily puzzle where the only person anyone can cheat is themselves.
What's next for Poople
- More variety in starting words and an optional harder mode for players who want a tougher daily.
- A small public daily puzzle endpoint so people can build their own front ends and bots around it.
- A deeper strategy guide that maps the common bridge words, the dead ends, and the golden transition words, generated from the same data that powers the answers.
- A richer solver that can show short meanings for the words along each path.
- Careful expansion only after the core pages are stably indexed and the domain has matured, so the site stays a focused word ladder home rather than a thin directory.
If you try it, I would love to know your instinct when you get stuck: do you swap the vowel first, or work backward from POOP?
Built With
- nextjs
- tailwindcss
Log in or sign up for Devpost to join the conversation.