DEV Community

Nikhil
Nikhil

Posted on

Building a Daily Puzzle Site: What the Tech Stack Actually Looks Like


There is a category of website that looks simple from the outside and is surprisingly interesting to build: the daily puzzle site.

Wordle is the obvious example. New York Times bought it for a reported seven figures. But the concept - one puzzle per day, resets at midnight, shareable result - is something any developer can build. I built DailyBrainHub - https://dailybrainhub.com - with six games running on this exact model and the technical decisions were more interesting than I expected.

The daily reset problem

The core mechanic of a daily puzzle site is that everyone gets the same puzzle on the same day. This sounds simple. It creates some interesting decisions.

Option 1: Server-generated puzzles. Your backend picks today's puzzle and serves it via API. Clean, controlled, easy to update. Requires a server.

Option 2: Deterministic client-side generation. You use today's date as a seed for a pseudo-random number generator. The same date always produces the same puzzle. No server needed.

function getDailyPuzzle(puzzleList) {
  const today = new Date();
  const seed = today.getFullYear() * 10000 + 
               (today.getMonth() + 1) * 100 + 
               today.getDate();

  const index = seed % puzzleList.length;
  return puzzleList[index];
}
Enter fullscreen mode Exit fullscreen mode

This is elegant but has a limitation: once you have served all puzzles in your list, you cycle back to the beginning. You need a large enough puzzle pool that the cycle is not noticeable for at least a year.

Storing progress without accounts

Account systems are friction. Wordle had no accounts. DailyBrainHub has no accounts. But you still need to remember whether a player has completed today's puzzle.

localStorage is the answer for most cases:

function saveTodayProgress(gameId, result) {
  const today = new Date().toISOString().split('T')[0];
  const key = `${gameId}_${today}`;
  localStorage.setItem(key, JSON.stringify(result));
}

function getTodayProgress(gameId) {
  const today = new Date().toISOString().split('T')[0];
  const key = `${gameId}_${today}`;
  return JSON.parse(localStorage.getItem(key));
}
Enter fullscreen mode Exit fullscreen mode

Using the date in the key means yesterday's data is automatically ignored without any cleanup logic. The player's progress resets naturally when the date changes.

The midnight reset

Players who are mid-puzzle at midnight need handling. The safest approach is to check the date when the page loads and when the player submits an answer. If the date has changed since the puzzle was loaded, show a message and refresh.

Shareable results without a backend

Wordle's viral mechanic was the emoji grid you could paste anywhere. No image, no link to a specific result, just text that conveyed the result visually.

function generateShareText(gameId, day, results) {
  const emoji = results.map(r => r.correct ? 'checkmark' : 'cross').join('');
  return `DailyBrainHub ${gameId} #${day}\n${emoji}\nhttps://dailybrainhub.com`;
}
Enter fullscreen mode Exit fullscreen mode

This generates text that works in WhatsApp, Twitter, anywhere. The result does not need to link to anything specific - it just needs to be intriguing enough that someone asks "what is this?"

What I would do differently

If I were starting over, I would build the share mechanic first, before any other feature. Everything else - the puzzle logic, the design, the blog - is secondary to the sharing loop. That loop is how daily puzzle sites grow. I built the games first and the share button last, which was the wrong order.


Top comments (0)