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.
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, shows you the available themes, and when you pick one, 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.
- Build your theme in the theme editor inside the Moonfin Web client and use Export JSON.
- Add the file to this repo as
themes/<your-id>.theme.json. - Open a pull request. The Validate themes check runs automatically and names anything that needs fixing.
Advanced: ids, the catalog manifest, and validation
- The
idinside the file must use lowercase letters, numbers,_, or-, and it has to be unique across the catalog. index.jsonis generated from the files inthemes/, and every pull request carries the regenerated manifest, somainis always ready to serve. Runnode scripts/generate-index.mjsfrom the repository root to rewrite it, and include it in the same commit. Without Node on hand, skip this and open the pull request anyway. The check comments the expectedindex.jsonon the pull request for you to paste in.- The validator confirms every required field is present and well formed (id, displayName, all color tokens as hex, borders, and so on), and that the optional fields a theme may carry, such as
isGlassorcolors.error, are the right type. It also confirmsindex.jsonmatchesthemes/. If anything is wrong, it names the file and the field to fix.
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 pushes tomain, and it fails if a theme is malformed orindex.jsonno longer matchesthemes/..github/workflows/pr-comment.ymlposts the result of that gate on the pull request.
Clients fetch the raw files directly from https://raw.githubusercontent.com/Moonfin-Client/Themes/main/.