Skip to content HtmlpressStatic site generator HtmlpressStatic site generator

Change theme

Keyboard shortcuts

Htmlpress

Updated

Htmlpress is the static site generator for humans and agents. It turns a folder of Markdown and HTML pages into a site. Each page keeps its own markup, and htmlpress adds one layout, one theme, a navigation and a live-reloading dev server. It is one Rust binary, installed from npm, PyPI or crates.io.

You or your agent write plain Markdown or semantic HTML, which agents know better than any templating language, and every page comes out looking like the same site: no framework, no build config, no utility classes.

Htmlpress is in technical preview: the page contract may still change before 1.0.

What you get

  • Just write Markdown or HTML. A page is any .md file with frontmatter, or any .html file, a full document or a bare fragment, whose <title> and <meta> tags do what frontmatter does; see Markdown pages.
  • A theme styled from the elements. Headings, tables, code blocks, <details>, <figure> and the rest look right with no classes, in light and dark mode.
  • Rich elements. Callouts, tabs, steps, cards, badges, file trees, sortable tables, terminals, package tabs (npm/pnpm/yarn/bun), Mermaid diagrams and embeds (YouTube, SoundCloud), all as htmlpress-* custom elements.
  • Navigation for free. A sidebar nested by folder, breadcrumbs, a table of contents, previous/next links and an "Edit on GitHub" link.
  • Multilingual. Translations beside their originals, a language picker, and the UI in seven bundled languages; see Translations.
  • Made for agents. Every build publishes a Markdown copy of each page, llms.txt and your agent skills; every command speaks JSON.
  • Themable. --htmlpress-* tokens, and per-file overrides of the layout, styles and components via a .htmlpress/ folder.
  • One binary. No runtime and no dependencies: a static site with sitemap.xml, robots.txt and a 404 page, ready for any host.

Quick start

You need nothing but the binary. Every channel ships the same binary at the same version, so pick the package manager the project already uses.

Install

curl -fsSL https://htmlpress.dev/install.sh | sh

Downloads the binary for your platform from the GitHub releases, checks its SHA-256 and puts it in ~/.local/bin. Set HTMLPRESS_VERSION to pin a version and HTMLPRESS_INSTALL_DIR to install elsewhere.

npm install --global gethtmlpress
# or run it without installing
npx gethtmlpress --version

The gethtmlpress package pulls in one platform package, such as @htmlpress/linux-x64, through an optional dependency. Installing with --omit=optional leaves the binary out.

pip install htmlpress
# or run it without installing
uvx htmlpress --version

The wheel for your platform carries the binary; no Python code runs.

cargo install htmlpress

Builds from source with the Rust toolchain, 1.88 or newer.

Prebuilt binaries cover Linux, macOS and Windows on x64 and arm64:

Platform npm package Rust target
Linux x64 @htmlpress/linux-x64 x86_64-unknown-linux-musl
Linux arm64 @htmlpress/linux-arm64 aarch64-unknown-linux-musl
macOS x64 @htmlpress/darwin-x64 x86_64-apple-darwin
macOS arm64 @htmlpress/darwin-arm64 aarch64-apple-darwin
Windows x64 @htmlpress/win32-x64 x86_64-pc-windows-msvc
Windows arm64 @htmlpress/win32-arm64 aarch64-pc-windows-msvc

On any other platform, build with cargo install htmlpress and, for the npm package, point HTMLPRESS_BINARY at the result.

Configure

Configuration is optional. To set the site's metadata, create htmlpress.yaml at the root of your project:

title: My docs
description: Documentation for my project
include: docs/**/*.html

Without include, every .html file in the project is a page; with it, only the matching ones are, served without the glob's base, so docs/usage.html is at /usage/. See Configuration File for every key.

Add content

  • docs/
    • index.html
    • getting-started.html
    • usage.html

Each page sets its title, description and order in tags a fragment may carry:

<title>Getting Started</title>
<meta name="description" content="Set up the project in five minutes." />
<meta name="order" content="1" />

<h1>Getting Started</h1>
<p>Welcome!</p>
---
title: Getting Started
description: Set up the project in five minutes.
order: 1
---

# Getting Started

Welcome!

See Frontmatter for what each tag means.

Run

htmlpress start    # dev server with live reload at http://localhost:8000
htmlpress build    # production build to .htmlpress/build/
htmlpress preview  # serve the production build locally
htmlpress clear    # remove .htmlpress/build/

That's the whole loop. Add .htmlpress/build/ to your .gitignore. This site is built that way from the rust/docs/ folder of the repository.

Project structure

A typical htmlpress site:

  • my-project/
    • htmlpress.yaml — configuration (optional)
    • index.html — the home page
    • guides/ — a sidebar group, named by its index.html
      • index.html
      • build.html
    • logo.svg — any other file, copied as-is
    • .htmlpress/ — escapes and the build output
      • layout.html
      • build/

A file under .htmlpress/ at a built-in's path, such as layout.html, styles/tokens.css or components/tabs/tabs.css, replaces the default, so you can customize the layout, the theme and components without forking. Run htmlpress escape <name> to copy a default into .htmlpress/ ready to edit.

Commands

htmlpress build [root]

Renders the project at root (default .) into root/.htmlpress/build, replacing what is there. --out / -o picks another folder; one that would hold the project, or a visible folder inside it, is refused, since its pages would be read back as sources.

$ htmlpress build docs
built 6 pages and 0 files into docs/.htmlpress/build

htmlpress start [root]

Builds the project, serves it on http://localhost:8000 and rebuilds on every change. Open pages reload themselves after each build. A failed build prints its error and shows it in the browser: over the pages already open, and in place of any page opened next. The server stays up, even when the first build fails, and the next good build reloads every page.

When 8000 is taken it tries 8001 and on to 8009, and prints the URL it got. --port / -p names one port instead (0 picks any free one). --host alone serves on every address, so a phone on the same network can open the site, and prints that URL too; --host <address> serves on one. With base in htmlpress.yaml the site is served under it, the printed URLs include it, and / leads there; restart after changing base. --open opens the site in the browser once it listens; --open <path> opens that page, under base. --out / -o works as for build.

$ htmlpress start docs --host
serving http://localhost:8000
network http://192.168.1.107:8000

htmlpress preview [root]

Builds the project for production and serves it as it will be deployed: no watching, no reload. Takes --port, --host, --open and --out like start.

htmlpress clear [root]

Removes the build output (--out to name another), with the same guard as build.

htmlpress escape [names…]

Copies built-in files into .htmlpress/ to edit them: a name is a path such as components/tabs/tabs.js, or a component's tag for all its files. Without names it lists every built-in file and whether the project has escaped it. --root / -r picks the project (default .). It refuses to overwrite a file; see Overriding/Escaping.

$ htmlpress escape htmlpress-tabs
escaped .htmlpress/components/tabs/tabs.css
escaped .htmlpress/components/tabs/tabs.js

For scripts and agents

The CLI is built with Fireargs, so every command speaks JSON. --json prints the result as JSON, and with a value it also takes the input as JSON:

$ htmlpress build docs --json
{
  "output": "docs/.htmlpress/build",
  "pages": 6,
  "files": 0
}
$ htmlpress build --json '{"root":"docs","out":"dist"}'

htmlpress start --json and preview --json never return, so they print {"url": "…", "network": []} as one line once the server listens.

htmlpress --llms prints every command's input and output schema as an MCP-shaped tool list, so an agent learns the CLI without reading this page.

Customization

Htmlpress is meant to look right with zero configuration and stay out of your way when you need more. Common customizations:

  • Site metadata: title, description, favicon, logo. See Site Metadata.
  • Sections: group pages by folder in the sidebar. See Article Sections.
  • External links: header and sidebar links to anywhere. See External Links.
  • Overriding/Escaping: replace the layout, any stylesheet or component from your project. See Overriding/Escaping.
  • AI agents: what every build publishes for agents. See AI Agents.

Documentation

Full documentation lives at htmlpress.dev:

Resources

License

MIT; see LICENSE.md.

Created with ❤ and Htmlpress

Actions

Edit on GitHubView as Markdown

Contents