Live at masterfool.github.io/WordTools — nothing to install, and it keeps working offline once the page has loaded.
A word finder for Waffle, Wordle, crosswords, and anything else where you know some letters and need the words that fit.
Type the word slot as it currently sits in your puzzle, tap each tile to mark it green / yellow / gray, and the matching words appear as you go. No build step, no server, no dependencies — it is a handful of static files.
Length sets how many tiles there are, from 3 up to 15. However long the word, the tiles stay on one line — they narrow to fit rather than wrapping.
The tile row is the word as it stands right now. Type the letters — they land gray — then click a tile (or press ↑/↓) to change its colour:
| Color | Means | Constraint |
|---|---|---|
| ⬜ gray | not in the word at all | bans the letter |
| 🟨 yellow | in the word, but not at this position | requires the letter, bans this slot |
| 🟩 green | this letter is at this position | fixes the position |
Colours cycle in that order, gray → yellow → green, each press committing a little more. Typing a new letter over a tile resets it to gray.
Duplicate letters work the way they do in Wordle: one yellow E plus one gray E
in the same row means "exactly one E" — you do not have to say so separately.
"Not here" sits under the tiles, one box per position. Type letters that cannot go in that slot. Use it for the Waffle case where a letter is gray in the perpendicular word, so you know it is not at the intersection — a yellow tile would be wrong there, because yellow also claims the letter is somewhere in this word. Letters already implied by the tiles show dimmed beneath each box.
The letter panel counts on top of the tiles. That is the whole trick, and it is why there is no min/max fiddling anywhere:
- Also contains
X— the word needs anotherXbeyond the ones already on the tiles. Use+for two or more extra. - No more of
X— the tiles show everyXthere is; no others.
So with SA__Y on the tiles (S green) and N,D gray:
- no more of S keeps the
Syou placed but rules out a second — SASSY drops out. - also contains S demands a second
S— SASSY becomes the only answer.
With an empty tile row these mean exactly what you would expect: "the word contains
X" and "the word has no X".
The A–Z grid is the whole alphabet at a glance. Click a letter to cycle neutral → also contains → no more of. A dot under a letter means the tiles already settled it: green placed, yellow required, gray ruled out.
Contradictory constraints produce an explanation, not a silent empty list.
Results are sorted most common first by default, with a divider before the words that are in the word list but that nobody actually says. Click any word to copy it. The whole query lives in the URL, so you can bookmark or share it.
fetch() and ES modules do not work over file://, so serve the directory:
python -m http.server 8000
- App — http://localhost:8000
- Engine tests — http://localhost:8000/test.html
- UI tests — http://localhost:8000/test-ui.html (drives the real page with synthetic events; run it in a normal browser window)
Nothing to install. No Node, no npm, no bundler.
index.html app shell
test.html engine tests
test-ui.html interaction tests, driven through a real page
css/style.css
js/engine.js pure constraint logic — filter, derive, merge, conflicts
js/dictionary.js loads and indexes the word list
js/state.js URL hash <-> app state
js/ui.js all DOM
data/words.txt 196,494 words, 3 to 15 letters
data/common.txt 39,893 words ranked by frequency
tools/build_common.py regenerates data/common.txt (needs network; output is committed)
See CLAUDE.md for the constraint model everything is built around.
data/words.txt is a list of 196,494 words of 3 to 15 letters, lowercase a–z
only, one per line. Two-letter words are not in it — they are no use in the games
this is for — and the list is curated, so words may be added or removed over time.
data/common.txt ranks 39,893 of those by frequency, derived from
hermitdave/FrequencyWords
(OpenSubtitles counts, MIT licensed). It is what powers "common first" sorting and
the "common words only" filter. If the file is missing the app falls back to A–Z
sorting and says so.