This repository holds the themes shown in the in-app Theme Store. Every Moonfin client reads index.json from here at runtime, lists what it finds, and lets you save any theme to your client so it behaves exactly like a server provided one.
Themes are plain JSON files built with the Moonfin theme editor, so you don't need to write any code to contribute one.
The Theme Store is a browser built into each Moonfin client. It fetches the catalog manifest, shows you the available themes, and when one is chosen, it downloads the theme, validates it, and registers it locally. Saved store themes are kept separate from server pushed themes, so syncing with your server never removes them.
The catalog manifest ships with the theme. index.json is generated from the files in themes/, and every pull request carries the regenerated manifest, so main is always ready to serve.
- Build your theme in the Moonfin theme editor inside of the Moonfin Web client and use Export JSON.
- Add the file as
themes/<your-id>.theme.json. Theidinside the file must use lowercase letters, numbers,_, or-, and it has to be unique across the catalog. - Regenerate the catalog and include it in the same commit. Run
node scripts/generate-index.mjsfrom the repository root to rewriteindex.json. Without Node on hand, skip this and open the pull request anyway, and the check in step 4 prints the file for you to paste in. - Open a pull request. The Validate themes check runs automatically. It confirms every required field is present and well formed (id, displayName, all color tokens as hex, borders, and so on), and that
index.jsonmatchesthemes/. If anything is wrong it names the file and the field to fix, and a stale manifest comes with the expectedindex.jsonprinted in the job summary.
themes/*.theme.jsonare the individual themes in the editor's export format.index.jsonis the generated catalog:{ schemaVersion, themes: [{ id, displayName, description, file }] }.scripts/validate-themes.mjsis the required-field validator, kept in step with the clients' own parsers.scripts/generate-index.mjsrebuildsindex.jsonfrom the contents ofthemes/..github/workflows/validate.ymlis the gate. It runs on pull requests and on pushes tomain, and it fails if a theme is malformed orindex.jsonno longer matchesthemes/.
Clients fetch the raw files directly from https://raw.githubusercontent.com/Moonfin-Client/Themes/main/.