Skip to main content

Build a Sudoku Solver with a Visual UI

Level: Beginner · Time: 30–40 min · Category: Browser app

Tags: HTML · CSS · JavaScript · Prompting · Algorithms

In this tutorial, you will make a webpage that can build a random sudoku puzzle, as well as a solver. The solver will be animated, so you can watch the algorithm work in real-time.

Note that this tutorial has minimal installation overhead. A coding assistant alone is adequate. The output will be an index.html file you open by double-clicking.

It is also a good project for seeing what an assistant can do. It is obvious when the task is done, you have the opportunity to plan with your assistant, and the step-by-step animation means the model output must be fully correct for the output to function.

Prerequisites​

That is the only setup required: no language runtime, no packages, no virtual environment.

Which assistant should I use for this one?

We will assume use of OpenCode in this tutorial. However, any assistant will work for this task. OpenCode or OpenWork will create and edit index.html for you, which is the smoothest experience. VS Code with Chat works the same way. Even Open WebUI works here. It cannot write files, but the task is simple enough that you can copy output directly.

Pick a model with the Tools badge if you want the assistant to write the file directly, and also check for Reasoning to ensure a smooth experience.

What you will do​

  • Set up a one-folder workspace and point your assistant at it.
  • Write one detailed prompt that specifies the whole app, including how "done" is measured.
  • Review the assistant's plan before any code is written.
  • Open the result in your browser and check it against a list.
  • Read the generated code and ask for a walkthrough of the part you do not understand.
  • Add two focused improvements, one at a time.

Build it step by step​

1. Create the workspace​

mkdir sudoku
cd sudoku

Then open OpenCode in that folder:

Open the OpenCode desktop app and point it at this project folder (sudoku).

Using OpenWork or VS Code instead? Open the sudoku folder in the app. Always open the folder, not a file, as assistants read the folder for context.

2. Ask for the app​

This is the whole project in one prompt. It is long, but every line removes a decision the model would otherwise have to guess at, which matters more with the models we host than it would with a frontier model. Paste it in as written.

CONTEXT
You are helping me build a browser sudoku app. I am a beginner. Everything must live in
one file, index.html, that I can open by double-clicking it. No build step, no npm,
no external libraries or CDN links.

GOAL
A 9x9 sudoku board with a button to generate a random puzzle and a button to solve it
one box at a time, visibly.

DONE MEANS
- I open index.html and see a 9x9 grid with clear 3x3 block borders.
- "New Puzzle" fills in a random solvable puzzle. Given numbers are bold and dark;
empty cells are blank.
- "Solve" fills the empty cells one at a time with a short delay so I can watch it,
in a different color from the given numbers.
- The solver is real backtracking, not a lookup table. Show me the backtracking:
when it undoes a wrong guess, briefly flash that cell red.
- A "Stop" button halts the animation mid-solve.
- A status line reads "Solved in N steps" when finished.

CONSTRAINTS
- Plain HTML, CSS, and JavaScript in one file. No frameworks.
- Comment the solver function so I can follow the algorithm.
- Under 300 lines.

PLEASE
1. Show me your plan in 4-6 bullets, then wait for me to say go.
2. Then write index.html.
3. Explain how to change the animation speed and the puzzle difficulty.

3. Read the plan before you say go​

You asked for a plan first on purpose. Read it. A good plan mentions a backtracking solver, a generator that removes cells from a completed grid (rather than placing random numbers and hoping), and an animation driven by a timer so the browser can repaint between steps.

If the plan is missing something, or includes an undesirable behavior, like installing an extra software, correct the assistant. An example of correction would be the following:

Your plan does not say how you will guarantee the generated puzzle is solvable.
Generate a complete valid grid first, then remove cells from it. Revise the plan.

This correction focuses on if the plan excludes solvability. As long as you write clearly and specifically, you can instruct the assistant to correct any of its mistakes.

Correcting a plan costs you a sentence; correcting finished code costs a rewrite. Of everything in this tutorial, this is the habit most worth keeping.

When the plan looks right, tell the assistant to start, in the way you told it to in the last step:

go

4. Open it in your browser​

The assistant should have written index.html in your folder. Open it by double-clicking. Or, if you want to use the terminal:

  • macOS: open index.html
  • Windows: start index.html
  • Linux: xdg-open index.html

Whenever you update the page, refresh your browser. There is no additional software step, so a refresh will give the latest version.

5. Check it against the list​

Because you made a plan, everything you need to check for has already been described. You can work through the list you wrote in the prompt:

CheckWhat to look for
Grid9x9, with visibly thicker borders around each 3x3 block.
New PuzzleDifferent numbers each time you click. Givens are bold and dark.
SolveCells fill one at a time, not all at once.
ColorsSolved numbers are visually distinct from the given numbers.
BacktrackingCells occasionally flash red as it undoes a wrong guess.
StopHalts mid-solve and stays halted.
StatusShows a step count when it finishes.

Then the real test: is the solution correct? Pick any row, column, and 3x3 block and confirm each contains 1 through 9 exactly once.

Common first-attempt failures, and the prompt that fixes each

These are common ways this program can fail. See if you can fix failures yourself. If not, the following focused follow-up prompts should get you there without a rewrite.

Everything fills in instantly. The solver ran to completion before drawing. Ask:

The solve happens instantly instead of one cell at a time. The recursive solver is
finishing before the browser repaints. Record each step into an array as the solver runs,
then play that array back with setTimeout so I can watch it. Change nothing else.

The generated puzzle has no solution, or more than one. Ask:

Generate a complete valid grid first using the solver on an empty board with randomized
number order, then remove cells from that completed grid. That guarantees a solution
exists. Change nothing else.

It pulled in a library or a CDN link. Ask:

Remove the external script tag. This must be one self-contained file with no network
requests. Reimplement that functionality in plain JavaScript.

Stop does not stop. Ask:

The Stop button does not halt the animation. Keep the timer ID in a variable and call
clearTimeout on it when Stop is pressed, and set a flag the playback loop checks.

The page is blank. Open your browser's developer console (F12) and paste the red error text to the assistant with:

The page is blank. Here is the console error: <paste it>. Fix only this.

6. Understand the code you were handed​

Before adding features, spend five minutes reading what you have. Reviewing is the part of this work where you add the most value.

note

If you are using a reviewer agent, ask for @reviewer look at index.html before continuing.

This is as straightforward as asking for help. We add a couple guardrails here, review the prompt for that. We focus on not changing code and establishing what we already know.

Walk me through the solve function line by line, as if I have never seen recursion.
Explain specifically what happens when it hits a dead end and has to back up.
Do not change any code.

Read the answer alongside the actual code. This is a good chance to learn about backtracking. While the assistant can write it for you, knowing the steps of it yourself can let you make better plans later. You can also ask more, later, as you come to understand it better.

If you want our writeup, read the following drop-down:

How the solver works, in plain language

Backtracking goes guess, check, undo as needed. The solver finds the first empty cell, tries the number 1, and checks whether it conflicts with anything in that row, column, or 3x3 block. If it fits, the solver moves to the next empty cell and does the same thing again. If it does not fit, it tries 2, then 3, and so on.

If every number from 1 to 9 fails in a cell, that means an earlier guess was wrong. The solver erases the current cell, steps back to the previous one, and tries the next number there. That step back is the "backtrack", which is what your red flashing cells are showing you.

Because it never accepts a number that conflicts, and it never gives up until it has tried everything, it always finds a solution if one exists.

7. Add one improvement at a time​

Now, you can upgrade the solver. We provide a structured process here, so you can get a feeling for how to iterate on successful assistant output.

Here, you will only request one feature at a time, and test after each. While this may seem slower than asking for all at once, if a single error occurs, you may find it difficult to learn which part of your request it came from. Just do one at a time.

This is good practice in the field, too. You hardly want to modify functional code with a list of new features, and come back with no features at all.

Difficulty selector:

Add a difficulty selector with Easy, Medium, and Hard that changes how many cells are
pre-filled when I click New Puzzle. Change nothing else.

Refresh and confirm all three difficulties produce visibly different boards and that Hard is still solvable.

Conflict checker:

Add a "Check" button that highlights any cell conflicting with another in its row, column,
or 3x3 block. Do not change the solver.

Manual play:

Let me type a number into an empty cell by clicking it and pressing a key from 1 to 9.
Typing 0 or Backspace clears the cell. Given cells stay locked and cannot be edited.
The Solve button must still work from whatever state the board is in.

Refresh and test after each one. If a change breaks something that used to work, say exactly that:

That change broke the Stop button, which worked before. Fix only that, and do not
change anything else.

8. Make it yours​

Pick one of these, look at the prompts used so far, and work with your assistant to implement one:

  • A timer, and a personal best time saved in localStorage.
  • A hint button that fills in one correct cell.
  • Keyboard navigation with the arrow keys.
  • A dark mode toggle.
  • An "undo" for your own moves.
  • Export the current board as text you can paste back in later.

More prompts to try​

If you are feeling curious, this is an opportunity to keep exploring, and here are some samples of what you can do:

  • Ask for the worst case: "Give me a puzzle known to be hard for backtracking solvers, and show me the step count difference against an easy one."
  • Ask it to teach: "Add a 'Explain this step' mode that shows, in a side panel, why the solver chose each number."
  • Ask for a second algorithm: "Add a toggle to solve with constraint propagation instead of plain backtracking, and compare the step counts."
  • Ask for a review: "Review this file for anything that will confuse me in six months. Do not rewrite it — list the issues."
  • Ask about accessibility: "Make the grid usable with a screen reader and keyboard only. Explain each change."

Troubleshooting​

  • Double-clicking the file opens a text editor, not a browser. Right-click the file → Open With → your browser.
  • Changes do not appear. Hard-refresh the page (Ctrl/Cmd+Shift+R). Also confirm the assistant saved to the same folder you opened.
  • The assistant keeps rewriting the whole file for a small change. Add "Do not rewrite the file. Show me only the lines that change." to your prompt, and put that rule in AGENTS.md.
  • The solver is correct but painfully slow to watch. Ask it to make the delay a variable at the top of the script, then tune it yourself.
  • Replies get worse the longer you work. Start a fresh session and tell it to read index.html first. Long sessions are expected to degrade in performance. You can learn why here.
  • The assistant cannot edit files at all. Your model probably lacks tool calling. Switch to a model with the Tools badge in the Voyager model list.

Next steps​