Themes
Themes control how your content looks. They're collections of JSX/TSX templates, components, and static assets.
Theme structure
themes/
└── my-theme/
├── theme.yaml # Theme manifest
├── templates/ # Page templates (one per content type)
│ ├── default.tsx # default.md → this template
│ ├── post.tsx # post.md → this template
│ ├── blog.tsx # blog.md → this template
│ └── error.tsx # 404 and error pages
├── components/ # Shared components
│ ├── layout.tsx # Base layout wrapper
│ ├── header.tsx
│ ├── footer.tsx
│ └── nav.tsx
├── islands/ # Interactive client components (Fresh islands)
│ ├── search.tsx
│ └── mobile-nav.tsx
└── static/ # Theme assets
├── styles.css
└── fonts/
The theme manifest
theme.yaml:
name: my-theme
version: 1.0.0
description: "A clean documentation theme"
author: "Your Name"
parent: default # optional: inherit from another theme
Using a theme
Set the active theme in config/site.yaml under the theme key:
theme:
name: my-theme
Common mistake:
theme:belongs inconfig/site.yaml, notconfig/system.yaml. Putting it insystem.yamlsilently has no effect — the theme won't load.
Package themes (JSR/npm)
Themes can be installed as version-pinned packages instead of copying files into themes/. Register packages under themes: and activate by name:
themes:
- name: paper
src: jsr:@dune/theme-paper@1.0.0
theme:
name: paper
src: jsr:@dune/theme-paper@1.0.0 # when the active theme *is* the package
Install from the CLI:
dune theme:install jsr:@dune/theme-paper@1.0.0 --activate
This writes the themes: entry, adds the import to deno.json, and syncs deno.lock. Package themes are resolved from the module graph — they are not extracted into themes/.
Local overrides stay in themes/my-brand/ with parent: pointing at a registered package name or pinned specifier. See Theme Inheritance.
Optionally pass theme-specific settings under custom::
theme:
name: my-theme
custom:
primaryColor: "#1a1a2e"
showSidebar: true
Or set it programmatically in dune.config.ts:
export default {
theme: {
name: "my-theme",
custom: {
primaryColor: "#1a1a2e",
showSidebar: true,
},
},
};