Muse lets you preview a coding font, a color theme, and a programming language together, live in the browser. Pick a font, pick a theme, pick a language — and see how the three actually look as a set before you commit to them in your editor.
It's a toy I built for myself, because I kept agonizing over editor fonts and themes and wanted a quick way to try combinations without installing anything. If you find it fun or useful too, that makes me happy.
No build step, no npm install, no backend — just HTML, a handful of ES modules, and JSON files. Fonts stream from CDNs, themes render through Shiki, and the whole thing deploys as static files on GitHub Pages.
- Mix and match — any font × theme × language combo, rendered instantly.
- Land on a surprise — your first visit picks a random font and theme, so you start somewhere you didn't expect. Your choices stick after that.
- Use fonts you already have — Muse checks for ~40 common coding fonts on your machine and lists the ones it finds, no download needed.
- Add your own font — paste a CSS URL or an
@font-facesnippet in the Add Font dialog. Saved locally, just for you. - Add your own theme — drop in any VSCode theme JSON. Also saved locally.
- Tweak the details — size, ligatures, italic comments.
- Search the sidebars — fuzzy filter the pills, arrow keys to move between them.
- Share a link — the URL captures your exact setup; send it and someone else sees the same thing. (Built-in fonts and themes travel; ones you added locally stay on your device.)
- Export to VSCode — the Export button hands you a ready-to-paste
settings.jsonfor the setup you landed on.
Everything lives in data/ as plain JSON. Adding something is just dropping in a file — you never touch shared code, so there's nothing to conflict with. If you make something nice, a PR is welcome but never expected (see CONTRIBUTING.md).
data/fonts/<id>.json:
{
"id": "fira-code",
"name": "Fira Code",
"stack": "'Fira Code', monospace",
"cssUrl": "https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;700&display=swap",
"ligatures": true,
"credits": "https://github.com/tonsky/FiraCode"
}The filename and the id field have to match — that's the canonical id used in URLs. Point cssUrl at a Google Fonts or Fontsource stylesheet. ligatures, weights, and credits are optional.
data/themes/<id>.json — any standard VSCode theme JSON (the kind with colors and tokenColors). The filename is the id; the name inside the file is just for display and can differ.
Shiki's built-in themes come for free (they're listed in data/themes/_builtin.json), so you only need a file for themes Shiki doesn't already ship. The ones committed here happen to be light themes — dark coverage comes from the built-ins.
A manifest at data/languages/<id>.json:
{
"id": "python",
"label": "Python",
"shikiLang": "python",
"sample": "data/samples/python.txt",
"summary": "Async ETL pipeline with dataclasses, decorators, and context managers."
}…and the sample code itself at data/samples/<id>.txt. shikiLang has to be a language Shiki knows. A good sample is a small, real program (roughly 50–100 lines) that shows off the language's syntax — not a pile of features glued together.
After adding any file, regenerate the catalog:
node scripts/rebuild-index.mjsCI does this automatically on push, so in a PR you can skip it — it's just handy locally.
python3 -m http.server 8000Then open http://localhost:8000. Any static server works; file:// does not (the browser blocks fetch() for modules and data). Node 18+ if you want to run the rebuild script.
index.html boots src/main.js, which wires up a small pub/sub store, the Shiki highlighter, font loading, and the UI. State syncs to both localStorage and the URL hash, and that's the whole thing.
If you want the wiring details — the invariants, the boot order, the gotchas I learned the hard way — they live in AGENTS.md.
It's a static site, so GitHub Pages from the repo root just works. The one requirement is the empty .nojekyll file at the root, which stops Jekyll from eating the _index.json and _builtin.json files. Push to main, CI rebuilds the catalog, Pages redeploys.