# MkDocs vs Htmlpress

> Rust + plain HTML vs Python + Jinja2 + Markdown.

[MkDocs](https://www.mkdocs.org) is a Python-based docs generator. Content is plain Markdown, layouts are Jinja2 templates, and themes are pip-installable Python packages. The de-facto theme is [Material for MkDocs](https://squidfunk.github.io/mkdocs-material/), which is what most consumers actually use.

## At a glance

| Axis               | Htmlpress                                             | MkDocs                                             |
| ------------------ | ----------------------------------------------------- | -------------------------------------------------- |
| Language / runtime | Rust (single binary, no runtime)                      | Python 3.8+                                        |
| UI framework       | None (plain HTML + CSS, `htmlpress-*` web components) | Jinja2 templates (HTML + CSS)                      |
| Build tool         | htmlpress binary                                      | MkDocs CLI                                         |
| Content format     | HTML and Markdown pages                               | Markdown (CommonMark + Python-Markdown extensions) |
| License            | MIT, self-hosted                                      | BSD-2-Clause, self-hosted                          |
| Output model       | Prerendered static                                    | Prerendered static                                 |

## Architecture

htmlpress is one Rust binary, installed from npm (`gethtmlpress`), PyPI or crates.io. It wraps each HTML page in one layout with a navigation and a theme; there is no bundler, no UI framework and no plugin API. Every built-in file — the layout, the styles, the scripts and each component — can be escaped: a file at the same path under `.htmlpress/` replaces it. On PyPI it ships as a binary wheel, so `pip install htmlpress` needs no Python code at run time.

MkDocs is a Python CLI. The site is configured through `mkdocs.yml`. Themes are pip-installable; the build pipeline runs Markdown content through Python-Markdown (or pymdown-extensions) and through Jinja2 templates. There's no JavaScript build step — interactivity in the rendered site is whatever the theme's templates emit.

Material for MkDocs adds a curated theme, a search index based on lunr.js, instant navigation, and a wide plugin ecosystem (`mkdocs-material` extras, plus the broader `mkdocs-*` plugin namespace on PyPI).

Content layout is unconstrained on the htmlpress side: it scans by glob (`include`/`exclude` in `htmlpress.yaml`, every `.html` file by default), and a page's URL follows its file path below the glob's base, so `docs/**/*.html` serves `docs/guide.html` at `/guide/`. There's no required `docs/` folder. The navigation is built from the folders and each page's `<meta name="order">`; a folder's `index.html` names its group. MkDocs reads from `docs/` (configurable via `docs_dir` in `mkdocs.yml`), with routes derived from file paths under that directory.

## Content surface

MkDocs accepts Markdown with frontmatter; htmlpress accepts HTML pages and Markdown with frontmatter alike. MkDocs extends Markdown through Python-Markdown extensions (admonitions, tabs, footnotes, definition lists) and `pymdown-extensions` (which adds the full Material syntax: `=== "Tab 1"` tabs, `:::note` admonitions, `++ctrl++` keyboard shortcuts, etc.). Customization beyond what extensions offer requires writing a Python plugin or overriding a Jinja template.

htmlpress pages are plain semantic HTML, styled by the theme from the elements themselves. Richer blocks are `htmlpress-*` custom elements (`htmlpress-callout`, `htmlpress-tabs`, `htmlpress-filetree`, `htmlpress-cards`, …), whose CSS and JS are linked only on pages that use the tag. A project adds its own tag with `.htmlpress/components/<name>/<name>.html`, which replaces the tag at build time. The same blocks are plain HTML elements here: `<dl>`, `<kbd>`, `<details>`.

htmlpress has no frontmatter: a page's metadata is its own `<head>` — `<title>`, `<meta name="description">`, `<meta name="order">`, `<meta name="layout">` and `<meta name="image">`; other `<head>` tags are kept. MkDocs reads `title`, `summary`, `tags` (with a plugin), `template`, and uses `mkdocs.yml` for navigation.

## Feature matrix

| Capability                  | Htmlpress                                                   | MkDocs                              |
| --------------------------- | ----------------------------------------------------------- | ----------------------------------- |
| Versioning                  | Partial (a section or a deploy per version)                 | Yes (via `mike` plugin)             |
| Internationalization (i18n) | Yes (translations, language picker, 7 bundled UI languages) | Yes (Material's i18n plugin)        |
| Search                      | Yes (built-in, client-side)                                 | Yes (built-in, client-side)         |
| Blog                        | No                                                          | Yes (Material's blog plugin)        |
| Changelog                   | No                                                          | No (manual)                         |
| Sitemap                     | Yes (with `site` set)                                       | Yes                                 |
| RSS                         | No                                                          | Via plugin                          |
| Themes                      | Escapes in `.htmlpress/` + `--htmlpress-*` tokens           | Theme packages + Jinja overrides    |
| Plugins                     | No (project components in `.htmlpress/components/`)         | Python plugins (`mkdocs-*` on PyPI) |
| Custom routes               | Any `.html` file; extra layouts in `.htmlpress/layouts/`    | No (content-only)                   |
| Standalone toolchain        | Single Rust binary (npm, PyPI or crates.io)                 | Python + pip                        |

## Output & deployment

Both tools produce static HTML + assets ready for any static host. MkDocs emits to `site/` by default; htmlpress emits to `.htmlpress/build/`.

htmlpress writes every page to static HTML in `.htmlpress/build/`, along with `robots.txt`, a `sitemap.xml` when `site` is set, a Markdown copy of each page, `llms.txt` and the agent skills under `.well-known/agent-skills/`. The `base` key serves the site under a sub-path. See [Deployment](/deployment/) for host guides.

## See also

- [Authoring](/authoring/) — htmlpress' HTML surface.
- [Customization](/customization/) — htmlpress' config keys and escapes.
- [Comparison](/comparison/) — back to the index.
