RhymePad
A scratchpad for poets & rappers that does live phonetic rhyme analysis of whatever you're writing. Type or paste lyrics into the pad and the rhyme structure is color-coded as you type — end rhymes, internal rhymes, slant rhymes, multisyllabic and multi-word rhymes — using the actual sounds (CMU Pronouncing Dictionary + a g2p phoneme fallback), not the spelling.
Yes, it knows orange rhymes with door hinge.
Live at https://rhymepad.org.
Run
$ uv run uvicorn app:app --reload
Then open http://127.0.0.1:8000.
The visual language
- Color = which sound. Every rhyme family gets its own hue.
- Brightness = rhyme strength, per word. Perfect rhymes blaze, slant rhymes sit back, consonance fainter still — and within a family the perfect anchors out-glow the loose slant attachments.
- A faint underline marks the rhyming tail of a word (under
ightintonight), so you see exactly where the rhyme lands. - Gray fill = a dead line ending that rhymes nothing.
- Dotted gold = a near-miss — a dead ending that's one phoneme from
rhyming with another ending (e.g.
hand/bond). A tiny edit locks it. - Hover any word and its whole family brightens across the page.
Toggles for rhyme · alliteration · rhythm (syllable-emphasis dots, "sheet music for your flow"). Hovering a word also names its family in the readout. Everything you see exports to a pixel-matching PNG.
How rhyme detection works
Every word is mapped to its CMU phonemes (pronouncing), with
lyric-friendly fallbacks (runnin' → running, possessives, made-up
words via g2p-en).
- Perfect rhymes share everything from the last stressed vowel on
(
tonight/light/flight→AY T). Matched anywhere in a line — that's the internal-rhyme detection. - Slant rhymes share just the vowel run (
hold/coal). - Multisyllabic & multi-word mosaics —
placement of creation,orange/door hinge— match across word boundaries. - Consonance catches shared vowel+coda endings (
bliss/exist).
The engine is taste-tuned toward what a listener actually hears:
rhymes don't cross stanza breaks, vowel families stay local, repeated
refrains are muted, and dialect mergers (NEAR vowel, cot-caught, nasal
and sibilant codas) are folded in. It deliberately rejects naive
vowel-matches — garbage/javascript, middle/unavoidable, and
smell like a do not rhyme, even though a coarser engine would link
them.
( parentheticals ) are real lyrics; inline (ad-libs) rhyme
internally but never claim the line-ending slot. Lines starting with
# (your notes) or [ (section headers) are skipped.
Using the engine without the web app
The rhyme engine is a framework-free module — no FastAPI, no HTTP:
import rhymes
result = rhymes.analyze_text("an orange door hinge\nporage")
# token spans, rhyme groups (with strength), schemes, meter,
# alliteration, near-misses, unanswered endings
rhymes.lookup_data("light", mode="rhyme") # ranked rhymes
rhymes.word_data("orange") # phonetic anatomy
app.py is just the FastAPI shell around it.
There's a CLI too:
$ rhymes analyze song.txt # color-coded rhyme families, in your terminal
$ rhymes density *.txt # which verse is the most rhyme-dense?
$ rhymes json song.txt # the full analysis payload
(uv run rhymes … inside this repo, or pip install rhymepad once
it's on PyPI.)
API
POST /api/analyze{"text": "..."}→ token spans, rhyme groups (with family strength), per-stanza schemes, per-line meter, alliteration, near-misses, and unanswered endingsGET /api/lookup?word=light&mode=rhyme|near|syn→ frequency-ranked rhymes / near rhymes (by syllable count) and WordNet synonymsGET /api/word?word=...→ pronunciation, senses, homophones
Everything is served locally — no external dictionary calls.
License
ISC. See LICENSE.
Release files for rhymepad 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| rhymepad-0.1.0.tar.gz | 39.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| rhymepad-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 66.5 kB
Release files / rhymepad-0.1.0.tar.gz
| Download URL | rhymepad-0.1.0.tar.gz |
|---|---|
| Size | 39.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
83667d2a12a3eb3a047527fca5eace00efdf987f3d89b659749a20c2c75e5b18
|
|
BLAKE2b-256 checksum How to use checksums |
861c26853812e21a70d40ecbcda551d422fe91ca1e5bbcae9a28617f1ed05a71
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.20 {"installer":{"name":"uv","version":"0.11.20","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / rhymepad-0.1.0-py3-none-any.whl
| Download URL | rhymepad-0.1.0-py3-none-any.whl |
|---|---|
| Size | 26.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
8cf254a27185d12a7815e16070945913c0d8af62ad4dc6b8a40de82ff70d200f
|
|
BLAKE2b-256 checksum How to use checksums |
5648ce6038dd76273abcf5ce459b66ad3674589aee70e5a7480e2d3f97249d02
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.20 {"installer":{"name":"uv","version":"0.11.20","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|