Back to themes Theme guide

Make a Marknote theme

A theme is one JSON file and no code. It names the colours for every surface Marknote paints — the window, the editor, the preview and exported HTML — and the app validates every key before it uses any of them. This page is the whole format, the rules a theme is held to, and how to get yours into the marketplace.

Where themes live

Each installed theme is a folder named for its id, holding one file:

%LocalAppData%\Marknote\themes\com.example.ember\
  theme.json

Drop a folder there and click Reload in Settings → Themes. A file that does not validate is listed with the exact path of the field that is wrong (colors.preview.scrollThumb, say), so nothing fails silently. Marknote's own seventeen looks are the same format — the built-in files are the reference.

theme.json

The full set of fields, with every colour key the app reads. Colours are #RRGGBB, #AARRGGBB, or the word transparent — nothing else.

{
  "schemaVersion": 1,
  "id": "com.example.ember",
  "name": "Ember",
  "version": "1.0.0",
  "author": "Your name",
  "description": "One sentence, sentence case.",
  "homepage": "https://example.com/ember",
  "license": "MIT",
  "appearance": "dark",
  "minMarknoteVersion": "1.9.0",
  "material": "none",
  "colors": {
    "chrome":  { "window": "#1A1412", "panel": "transparent", "pane": "#221A17", "dialog": "#221A17" },
    "accent":  { "color": "#FF7A3D", "ink": "#1A1412" },
    "editor":  {
      "bg": "#221A17", "activeLine": "#2C221E", "selection": "#3D2D26", "gutter": "#7A6A62",
      "fg": "#F2E6DC", "fgStrong": "#FFFFFF",
      "comment": "#7A6A62", "string": "#B8D68C", "regexp": "#F0C674", "number": "#F0A868",
      "keyword": "#FF7A3D", "operator": "#E6B8A2", "func": "#8FD3C7", "type": "#F0C674",
      "heading": "#FF7A3D", "link": "#8FD3C7",
      "brandCaret": false
    },
    "preview": {
      "fg": "#F2E6DC", "fgSecondary": "#D6C6BA", "bg": "#221A17",
      "codeBg": "#1A1412", "codeBorder": "#3D2D26",
      "quoteBorder": "#FF7A3D", "quoteBg": "#1A1412",
      "link": "#8FD3C7", "rule": "#3D2D26",
      "tocBg": "#2C221E", "headerBg": "#1A1412",
      "scrollThumb": "#4D7F7F7F", "scrollThumbHover": "#807F7F7F"
    },
    "code": { "highlight": "github-dark-dimmed", "mermaid": "dark" }
  },
  "css": ""
}
Field Required Notes
schemaVersion Yes Always 1. A file written for a newer schema is refused rather than half-applied.
id Yes Reverse-DNS, lower case: letters, digits and hyphens in dot-separated segments. Use a domain you own. uk.marknote.* is reserved for the built-ins.
name Yes Shown in the picker. Sentence case, 24 characters or fewer.
version Yes Semver, no leading v. The marketplace offers an update when it rises.
appearance Yes light or dark. Picks the side of the picker the theme lists on and the stock controls' base look.
author, description, homepage, license No Shown on the card and the detail page.
minMarknoteVersion No 1.9.0 or later. Older apps skip the theme with a clear message.
material No none (default), mica, mica-alt or acrylic. A material only shows through chrome surfaces set to transparent.
colors.chrome Yes window (title bar and behind the panels), panel (rail and sidebar), pane (editor and preview panes, and the selected tab), dialog. An optional flyout colours menus.
colors.accent Yes color and ink — the accent and what is written on it. Hover and pressed shades are derived, always moving away from the ink.
colors.editor Yes The sixteen keys above. Or {"stock": true} for CodeMirror's own look on that side. brandCaret keeps Marknote's red caret.
colors.preview Yes All thirteen keys. They become the preview's CSS variables, and the exported HTML's.
colors.code No highlight: github or github-dark-dimmed; mermaid: default, dark, neutral, forest or base. Both default by appearance.
css No Extra CSS for the preview only, 64 KB at most, and checked: nothing that fetches, runs, or escapes — no url(), @import, @font-face, backslashes or angle brackets. A theme that breaks the rule is refused outright, with the reason.

The contrast bar

Every theme in the marketplace clears the same bar, measured with the WCAG ratio:

  • 4.5:1 — preview text and secondary text on the page and on code blocks; editor text on its background; the accent's ink on the accent's rest, hover and pressed fills.
  • 3:1 — links and headings on their background.
  • 2.5:1 — line numbers on the editor background. A cue you find, not text you read; every palette sets them in its comment tone.

The detail page of every listed theme shows its table. To measure yours before submitting, run the lint from a checkout of the Marknote repo — it validates the file exactly as the app will and prints the same table:

dotnet run --project tools/ThemeLint -- path\to\theme.json

Submitting to the marketplace

  1. Fork wearemarknote/themes and add themes/<your-id>/theme.json.
  2. Open a pull request. The template is the review checklist; a workflow runs the lint on your file.
  3. A maintainer reads the file — it is small by construction — checks the contrast table, and takes the screenshot from a shared sample note so every listing is shot the same way.
  4. Once merged, the theme is listed here and appears in the app's gallery within the hour.

Themes are free for everyone, and stay yours: the file carries your name and licence. Palettes that belong to a project — Nord, Catppuccin, Dracula — should credit it in homepage and keep to a licence the project allows.

Rejoining the server...

Rejoin failed... trying again in seconds.

Failed to rejoin.
Please retry or reload the page.

The session has been paused by the server.

Failed to resume the session.
Please retry or reload the page.