The static site generator that produces truly portable HTML files.
Nomad takes your Markdown or HTML files and produces self-contained HTML documents where every resource β CSS, JavaScript, images, video, audio, PDFs, fonts β is embedded directly into the file. No external dependencies, no broken links, no missing assets. Just a single .html file you can open anywhere.
Ever tried sharing an HTML page only to find the images are missing, the styles are gone, or the scripts won't load? Nomad solves this by baking everything into one file.
Perfect for:
- π Documentation β Ship a single HTML file that works offline, on any device
- π§ Email-friendly reports β Attach a self-contained HTML report with charts, images, and styling intact
- π Markdown publishing β Write in Markdown, distribute as a polished HTML page
- ποΈ Archiving websites β Freeze a project's pages into portable snapshots
- π Saving web pages β Download any URL and capture it as a self-contained offline HTML file
- π§© Prototyping β Convert multi-file HTML/CSS/JS projects into single-file demos
- π Teaching materials β Create handouts and tutorials that just work when opened
- Markdown β HTML β Converts
.mdfiles using a fast built-in GFM-compliant renderer (tables, task lists, strikethrough, heading IDs, autolinks) - Resource embedding β Automatically inlines images, stylesheets, scripts, video, audio, PDFs, fonts, favicons,
srcset/<picture>,<track>subtitles, and inlinestyle=""URL references as base64 data URIs - File includes β Use
{{embed:path/to/file}}in Markdown to include raw text, HTML components, or any snippet - Directory processing β Recursively convert an entire folder of
.mdand.htmlfiles in one command, with auto-generated index page - HTML minification β Optionally strip comments, collapse whitespace, compress inline CSS/JS, and remove source maps with
--minify - Custom templates β Use
--templateto wrap your content in a custom HTML layout with{{content}},{{title}}, and frontmatter variables - Frontmatter metadata β YAML frontmatter in Markdown is parsed and applied as
<meta>tags and template variables - Table of contents β Auto-generate a
<nav class="toc">from headings with--toc - Syntax highlighting β Code blocks with language annotations get inline syntax highlighting (no external CSS/JS required)
- Watch mode β Rebuild automatically on file changes with
--watch - Verbose diagnostics β See warnings for skipped or missing resources with
--verbose - TypeScript transpilation β
<script src="app.ts">files are automatically transpiled to JavaScript before embedding - File size limits β Skip embedding files larger than a threshold with
--max-size - Cross-platform β Prebuilt executables for Linux, macOS, and Windows (x64 & ARM64) β no runtime required
- Remote page capture β Download any web page by URL and embed all its resources into a single portable file
Grab the latest release for your platform from the Releases page:
| Platform | Binary |
|---|---|
| Linux x64 | nomad-linux-x64 |
| Linux ARM64 | nomad-linux-arm64 |
| macOS x64 | nomad-darwin-x64 |
| macOS ARM64 | nomad-darwin-arm64 |
| Windows x64 | nomad-windows-x64.exe |
| Windows ARM64 | nomad-windows-arm64.exe |
Place the binary somewhere on your PATH and you're ready to go.
Requires Bun v1.3+.
# Clone the repository
git clone https://github.com/user/nomad-ssg.git
cd nomad-ssg
# Install dependencies
bun install
# Run directly
bun run src/index.ts --help
# Build for the current platform
bun build --compile src/index.ts --outfile nomad
# Build for all platforms
bun run build# Convert Markdown and print to stdout
nomad document.md
# Convert Markdown and write to a file
nomad document.md -o document.html
# Convert an HTML file (embeds all local resources)
nomad page.html -o portable-page.html# Process all .md and .html files recursively, output to ./out
nomad my-site/
# Process into a specific output directory
nomad my-site/ -o dist/# Produce minified output (smaller file size, source maps stripped)
nomad document.md -o document.html --minify
# Short flag works too
nomad document.md -o document.html -mWrap your content in a custom HTML layout. The template can use {{content}} for the rendered body, {{title}} for the page title, and any frontmatter key like {{author}}:
<!-- template.html -->
<!DOCTYPE html>
<html>
<head><title>{{title}} - My Site</title></head>
<body>
<header>By {{author}}</header>
<main>{{content}}</main>
</body>
</html>nomad document.md -o page.html --template template.htmlAdd YAML frontmatter to your Markdown files. The metadata is used for <meta> tags and template variables:
---
title: My Page
author: Jane Doe
description: A detailed guide
---
# My Page
Content goes here.Auto-generate a navigable table of contents from your document's headings:
nomad document.md -o page.html --tocAutomatically rebuild when source files change:
nomad my-site/ -o dist/ --watchSee warnings for resources that couldn't be found or were skipped:
nomad page.html -o out.html --verboseSkip embedding files over a certain size to keep output manageable:
# Skip files larger than 500KB
nomad page.html -o out.html --max-size 500000TypeScript files referenced via <script src="..."> are automatically transpiled to JavaScript before being embedded. Type annotations, interfaces, and other TypeScript-specific syntax are stripped, producing clean JS that runs in any browser:
<!-- Input -->
<script src="app.ts"></script>
<!-- Output (after processing) -->
<script>const greeting = "Hello";console.log(greeting);</script>Both .ts and .tsx files are supported. Any type="text/typescript" attribute is automatically removed from the resulting <script> tag.
Download a remote web page and convert it to portable HTML with all resources embedded:
# Download a page and write to a file
nomad https://example.com -o example.html
# Download and print to stdout
nomad https://example.com
# Download and minify in one step
nomad https://example.com -o page.html --minifyAll images, stylesheets, scripts, and CSS url() references on the remote page are fetched and embedded as data URIs, producing a fully self-contained HTML file.
Include external files directly into your Markdown with the {{embed:...}} syntax. The path is resolved relative to the Markdown file.
# My Page
Here is a reusable navigation bar:
{{embed:components/nav.html}}
And some content below.This is useful for:
- Reusable HTML components (headers, footers, navbars)
- Including code samples from external files
- Composing pages from smaller fragments
Embeds are resolved recursively β an embedded file can itself contain {{embed:...}} directives.
nomad <input> [options]
| Option | Description |
|---|---|
<input> |
Input file (.md, .html), directory, or URL |
-o, --output |
Output file or directory |
-m, --minify |
Minify and compress the output HTML |
-t, --template |
HTML template file with {{content}}, {{title}} |
--toc |
Generate a table of contents from headings |
-w, --watch |
Watch for file changes and auto-rebuild |
--verbose |
Show warnings for skipped/failed resources |
--max-size <n> |
Max file size in bytes to embed (skip larger) |
-h, --help |
Show help |
-v, --version |
Show version |
- Markdown files are parsed for YAML frontmatter, then converted to HTML using Bun's built-in CommonMark/GFM renderer
{{embed:...}}directives are resolved and inlined before conversion- Syntax highlighting is applied to fenced code blocks with language annotations
- Table of contents (optional) is generated from heading IDs and prepended to the body
- Templates (optional) wrap the body in a custom HTML layout with variable substitution
- HTML files are scanned for local resource references:
<img src="...">and<img srcset="...">β embedded asdata:image/...;base64,...<link rel="stylesheet" href="...">β replaced with inline<style>(CSSurl()references are also embedded)<link rel="icon" href="...">β favicon embedded as data URI<script src="...">β replaced with inline<script>(.ts/.tsxfiles are transpiled to JS)<video>,<audio>,<embed>,<object>,<iframe>β embedded as data URIs<track src="...">β subtitle/caption files embedded as data URIsstyle="...url(...)..."β inline style URL references embedded
- Minification (optional) strips comments, collapses whitespace, compresses inline CSS/JS, and removes source map references
- The result is a single self-contained HTML file with zero external dependencies
- Remote URLs are fetched directly β the same embedding pipeline applies to all linked resources on the page
- Directory builds auto-generate an
index.htmllisting all pages
Remote URLs (http://, https://) in local files are fetched and embedded alongside local resources. When the input itself is a URL, all resources on that page are likewise fetched and embedded.
# Run the test suite
bun test
# Run a specific test file
bun test tests/embedder.test.tsMIT