(tools:themes)=
# Website themes

QuantEcon maintains its own themes so the lecture sites share one look and one set of
reading affordances (launch buttons, downloads, dark mode, "on this page" navigation).
There are **three** theme repositories, and they are at very different stages — one is in
production, one is being built for the migration to Jupyter Book 2, and one is an early
experiment.

| Theme | Renders | Status | Distribution |
|---|---|---|---|
| [quantecon-book-theme](https://github.com/QuantEcon/quantecon-book-theme) | Sphinx / Jupyter Book **1** | **Production** — every published lecture site | [PyPI](https://pypi.org/project/quantecon-book-theme/) |
| [quantecon-theme.mystmd](https://github.com/QuantEcon/quantecon-theme.mystmd) | MyST (`mystmd`) / Jupyter Book **≥ 2** | **In development** — feature parity ahead of the migration | zip on each GitHub Release |
| [quantecon-sphinx-theme](https://github.com/QuantEcon/quantecon-sphinx-theme) | Sphinx (general documentation) | **In development** — experimental, awaiting a go / no-go | unreleased |

```{important}
Only the first two are load-bearing. `quantecon-sphinx-theme` has no releases, is not on
PyPI, and has no downstream users — do not reach for it when starting a new project.
```

## quantecon-book-theme

The theme behind **every published QuantEcon lecture series** — `lecture-python.myst`,
`lecture-python-intro`, `lecture-python-programming`, `lecture-python-advanced.myst`,
`lecture-jax`, `lecture-julia.myst`, `lecture-datascience.myst`, `lecture-dp`,
the Chinese translations, and others.

It is a Sphinx theme (`html_theme = quantecon_book_theme`) that inherits from
[`pydata-sphinx-theme`](https://pydata-sphinx-theme.readthedocs.io/) and is compiled with
[`sphinx-theme-builder`](https://sphinx-theme-builder.readthedocs.io). Because it runs
*at build time inside the lecture repo*, it can read the git history — which is where the
last-modified dates and the per-lecture changelog dropdown come from.

To install:

```bash
pip install quantecon-book-theme
```

and in `_config.yml`:

```yaml
sphinx:
  config:
    html_theme: quantecon_book_theme
```

```{note}
The shared {ref}`quantecon environment <quantecon-environment>` pins a specific version of
`quantecon-book-theme` so `html` output stays consistent across projects — take the version
from there rather than installing unpinned.
```

Notable features: git-derived last-modified date and changelog, launch buttons
(BinderHub / Colab / JupyterHub), collapsible `stderr` output in notebook cells,
configurable code highlighting (`qetheme_code_style`), colour schemes, multilingual
support with a language switcher, and RTL layout.

- **Docs** — <https://quantecon.github.io/quantecon-book-theme/>
- **Requires** — Python ≥ 3.12, Sphinx 7–8
- **Tested with** — `tox`, `pytest`, and Playwright visual regression against
  [quantecon-book-theme-fixtures](https://github.com/QuantEcon/quantecon-book-theme-fixtures);
  see {ref}`Visual regression testing <tools:playwright>`

## quantecon-theme.mystmd

The theme for the **next generation** of lecture sites. Jupyter Book 2 replaces Sphinx with
the [MyST engine](https://mystmd.org), so the Sphinx theme above cannot come with it —
`quantecon-theme.mystmd` is its replacement, and it is being brought to feature parity
ahead of the migration.

It is a [MyST site template](https://mystmd.org/guide/website-templates) built with
Remix + Tailwind CSS, tracking the upstream
[`jupyter-book/myst-theme`](https://github.com/jupyter-book/myst-theme) `book` theme. It is
**not published to npm**: each release attaches a `quantecon-theme.zip`, and projects pin
that URL in `myst.yml`:

```yaml
site:
  # Pinned theme release; bump the vX.Y.Z to take a new version
  template: https://github.com/QuantEcon/quantecon-theme.mystmd/releases/download/v2.2.0/quantecon-theme.zip
```

The current release is **v2.2.0**. `lecture-wasm` is the first lecture repo consuming it.

```{note}
**The architectural constraint worth knowing.** The Sphinx theme runs at build time inside
the lecture repo and can shell out to `git`; the MyST theme runs as a *runtime server* over
pre-built content JSON and never sees the repository. Anything derived from the source repo
— git history, last-modified dates, computed launch paths — therefore cannot be computed by
the theme, and must be injected upstream into each page's frontmatter (by a MyST plugin, by
`mystmd` itself, or by a CI step). The theme's job is only to *render* it.
```

Launch buttons target **Google Colab** and a private JupyterHub, using the `.notebooks`
repo-suffix convention by default and configurable under `site.options` in `myst.yml`.
BinderHub is deliberately not offered — it proved unreliable in practice.

The remaining parity gaps are tracked in the repo's `PLAN.md` — git-history headers,
Thebe/live compute, configurable code highlighting and colour schemes, the language
switcher, and RTL support.

```{seealso}
This repository was renamed from **`quantecon-theme-src`**, and supersedes the archived
[`quantecon-theme`](https://github.com/QuantEcon/quantecon-theme) (which bundled the built
theme). Old links redirect, but use the current name in new writing.
```

## quantecon-sphinx-theme

```{warning}
**In development — not ready for use.** This theme has no tagged release and is not on
PyPI, so there is nothing stable to depend on yet. If you are choosing a theme today, use
`quantecon-book-theme` for a Jupyter Book 1 site, or `quantecon-theme.mystmd` if you are
building on Jupyter Book 2 / `mystmd`.
```

A **clean, content-focused Sphinx theme for scientific documentation** — conceived as a
brand-neutral alternative to `quantecon-book-theme` for smaller or non-core documentation
sites.

Development has not resumed since the initial push. The whole repository was written in a
single session on 24 February 2026: 15 commits, one author, no tags, no releases, and no
PyPI package despite the `pip install` line in its README. The one downstream evaluation
(`lecture-python-programming#475`) was closed unmerged, so it has no users.

[Issue #6](https://github.com/QuantEcon/quantecon-sphinx-theme/issues/6) asks for a
go / no-go, and the strategic question gates everything else: the project has two
conflicting purposes on record (a brand-neutral upstream base, versus a second QuantEcon
theme for non-core series), its name depends on which one wins, and it targets Sphinx /
Jupyter Book 1 just as the lecture repos move to Jupyter Book 2. Known defects — inline
math, the RHS table of contents, a broken border, author/translator attribution — are
tracked in issues #1–#4.

## Working on a theme

- Both production themes are covered by **Playwright visual-regression tests** — see
  {ref}`Visual regression testing <tools:playwright>` for how to run them, read a failure,
  and regenerate baselines.
- The linters, formatters, and build tooling used in each repo are indexed on
  {ref}`Development tooling <tools:development>`.
- Changing a theme changes *every* site that consumes it. Pin-and-bump is deliberate:
  lecture repos take a new `quantecon-book-theme` version through the shared environment,
  and a new `quantecon-theme.mystmd` version by bumping the release URL in `myst.yml`.
