DEV Community

Vago Neue J
Vago Neue J

Posted on

Why I Built a Printable Puzzle Generator and What It Taught Me About Web App Architecture

Last year I was stuck in one of those motivational dead zones that every developer hits eventually. My day job was fine but unstimulating. I wanted to build something — anything — just to remember what it felt like to ship a project from scratch without a product manager breathing down my neck about sprint velocity.

The idea came from an unlikely place: my daughter's homework.

She was in third grade and working on her multiplication tables. My wife asked me to print out a multiplication chart so she could hang it next to her desk. Simple enough, right? Except every site I found was either covered in ads, required some weird sign-up, or produced a blurry, ugly PDF that looked like it was designed in 1998.

I thought: I'm a web developer. I can build this in a weekend. And that thought spiraled into a three-month side project that taught me more about practical web architecture than I expected.

The Seed of the Idea

The multiplication chart thing was genuinely the starting point. I spent a Saturday afternoon building a clean, responsive web page that generates a Multiplication Chart Printable with customizable dimensions, clean typography, and a CSS print stylesheet that actually produces a good-looking result when you hit Ctrl+P.

That was about four hours of work, and honestly it was satisfying in a way that my day-to-day work rarely is. There's something deeply gratifying about building a tool that does one thing well. No login required. No feature creep. No "premium tier." Just a page that solves a specific problem cleanly.

But then I got curious. What other simple printable tools are people searching for? I started poking around Google Trends and keyword tools, and I discovered an entire ecosystem of people looking for printable resources online — graph paper, lined paper, dot grids, calendars, planners, sheet music, and (this one surprised me) Sudoku puzzles.

Turns out there's a huge demand for printable Sudoku. Like, way more than I expected. And most of the existing solutions were, again, either ad-heavy nightmares or limited in their puzzle generation capabilities.

So I built Sudoku Printable as my second project, and this is where things got technically interesting.

The Architecture Problem: Generating Puzzles on the Client

Here's the thing about Sudoku generation that I didn't fully appreciate before I started: creating a valid Sudoku puzzle is a constraint satisfaction problem, and generating puzzles with a unique solution at specific difficulty levels is genuinely non-trivial.

My first instinct was to do what a lot of developers do — throw the heavy lifting to the backend. Spin up a Node server, write a puzzle generator in JavaScript, cache generated puzzles in Redis, serve them via API. Classic architecture.

But I wanted this to be a zero-cost project. No server. No database. No monthly hosting bill. Just a static site.

That constraint forced me to think differently. Everything had to happen in the browser.

The puzzle generation algorithm works in two phases. First, you generate a complete, valid Sudoku grid using a backtracking algorithm. You start with an empty 9x9 grid, place numbers according to Sudoku constraints (no repeats in any row, column, or 3x3 box), and when you hit a dead end, you backtrack and try a different number. This is basically a depth-first search with constraint pruning.

The second phase is where difficulty comes in. You start with the completed grid and strategically remove numbers, checking after each removal that the puzzle still has exactly one solution. The number of cells you remove and the patterns of removal determine the difficulty. Easy puzzles might leave 35-40 given numbers. Hard puzzles might leave 25 or fewer.

That uniqueness check is the expensive part. For each removal, you need to verify that there's still only one way to solve the puzzle. I implemented a solving algorithm (also backtracking-based) that counts solutions and stops as soon as it finds a second one.

On modern hardware, this runs in the browser in under a second for most puzzles. But on older devices or when generating multiple puzzles at once (for a printable sheet of six puzzles), I hit performance issues.

The Web Worker Solution

My fix was to move puzzle generation into a Web Worker. This keeps the main thread free for UI updates and prevents the browser from becoming unresponsive during generation.

The architecture ended up looking something like this: the main thread sends a message to the worker requesting N puzzles at a given difficulty. The worker generates them in the background and posts them back when done. The main thread then renders them into the DOM and applies print-specific CSS for clean output.

This pattern — offloading CPU-intensive work to Web Workers — is something I'd read about plenty of times but never had a genuine reason to implement. Building this puzzle generator was the first time the pattern clicked for me in a practical sense.

One thing I learned: communicating complex data between the main thread and a worker via postMessage is straightforward, but you need to be careful about data serialization. I was initially passing puzzle objects with methods attached, which doesn't work because postMessage uses the structured clone algorithm, which strips functions. The fix was to pass plain data objects and reconstruct the puzzle instances on the receiving side.

Print Stylesheets Are an Underrated Skill

A surprising amount of my development time went into print CSS. And I think this is a genuinely underrated skill in the web development world.

Most web developers never think about how their pages look when printed. And for most web apps, that's fine — nobody prints a dashboard. But for a printable resource generator, the print output is the entire product.

I learned a bunch of things I didn't know:

The @media print query lets you completely restyle the page for printing. I hide all navigation, buttons, and interactive elements, and expand the puzzle grid to fill the page.

The @page CSS rule lets you set page margins, orientation, and size. For puzzle sheets, I use @page { size: letter portrait; margin: 0.5in; } to get consistent output across different printers.

Page breaks are controlled with break-before, break-after, and break-inside properties. When printing a multi-page sheet of puzzles, you need to tell the browser where to break pages. Getting this right took more trial and error than I'd like to admit.

Color accuracy is another consideration. What looks great on screen might not print well, especially on lower-quality printers. I ended up using high-contrast black-and-white designs specifically because they print reliably on any hardware.

The Multiplication Chart: Simpler But Instructive

Going back to the multiplication chart project — this one was architecturally much simpler, but it taught me a lot about responsive layout and dynamic content generation.

The chart is essentially a large HTML table generated by JavaScript. You choose the range (say, 1 through 12, or 1 through 20), and the JavaScript generates the corresponding table with properly calculated products.

The interesting challenge was making this look good at any size. A 12x12 chart fits neatly on a letter-sized page. A 20x20 chart requires smaller font sizes and tighter cell spacing. A 25x25 chart starts pushing the limits of what's readable on a single printed page.

I ended up using CSS Grid for the layout (instead of an HTML table element) because it gave me more control over cell sizing and spacing. The grid dimensions are set dynamically via CSS custom properties that JavaScript updates when the user changes the chart range.

One thing I'm proud of: the print output of the multiplication chart is genuinely clean. No border artifacts, consistent cell sizes, centered text in every cell, and a clear header row and column that make the chart easy to read on paper. Getting there required a bunch of small CSS tweaks that don't show up in any tutorial but make a real difference in the final product.

What This Taught Me About "Small" Projects

There's a tendency in our industry to devalue small projects. If you're not building the next SaaS platform or open-source framework, it doesn't "count" as real engineering. I've heard this attitude from hiring managers, from colleagues, and honestly from my own internal monologue.

But building these printable tools taught me more about practical web development than a lot of the "serious" projects I've worked on.

I learned about constraint satisfaction algorithms by building the Sudoku generator. I learned about Web Workers by needing them for a real performance problem. I learned about print CSS by having to deliver a real print-quality product. I learned about responsive design by making charts look good at ten different sizes.

And critically, I learned about shipping. These projects have users. Real people visit these sites, generate puzzles and charts, and print them out for their kids, their classrooms, their brain-training routines. That feedback loop — build a thing, ship it, watch people use it — is the whole point of being a developer, and small projects give you that loop much faster than large ones.

The Technical Takeaways

If you're looking for a side project that teaches practical web skills, I'd genuinely recommend building a printable resource generator. Here's why:

Client-side rendering gives you practice with DOM manipulation, dynamic content generation, and performance optimization without the complexity of a backend.

Print CSS is a real skill that most developers lack. If you ever need to generate reports, invoices, or any printable output from a web app, you'll be glad you learned it.

Algorithmic thinking shows up in surprising places. Sudoku generation is a legitimate computer science problem. So is optimizing layout algorithms for different chart sizes.

Static site architecture forces you to think creatively about what's possible without servers. My hosting cost for these projects is literally zero because they're deployed as static sites on Netlify.

SEO and discoverability are real-world skills. Getting these sites in front of users required learning about metadata, page structure, content strategy, and search intent — all things that make you a more well-rounded developer.

Where I Am Now

Both projects get steady traffic. Nothing life-changing — a few thousand visitors per month each — but enough to validate that people find them useful. I don't monetize them, and I don't plan to. They exist because I needed a project, and they continue to exist because they solve real problems for real people.

The code is straightforward. The architecture is simple. The pages load fast and work offline (both are PWAs). And every time I hear my daughter using her multiplication chart, or see a comment from a teacher saying they use the Sudoku printable for their classroom, I'm reminded why I got into this field in the first place.

Not every project needs to be ambitious. Sometimes the best thing you can build is the simplest thing that actually helps someone.


If you're in a creative rut, try building something printable. The constraints are different from typical web development, the skills transfer directly to professional work, and the feeling of holding a physical artifact that your code produced is weirdly satisfying. Give it a shot.

Top comments (0)