help-book

Help Book

Release License: MIT No Build Step Vanilla JS

A standalone, drop-in documentation system for any web project. No build step, no npm, no framework — just static files. Mintlify-inspired aesthetic, macOS-Settings layout, dark mode out of the box.

Live demo: https://leminkozey.github.io/help-book/help/

Preview

Light Dark
Light mode Dark mode

What it does

Copy the help/ folder into your project, edit chapters.json, write markdown — done. Your project has a full documentation site.

Features:

Quick Start

One line, in your project root:

curl -fsSL https://raw.githubusercontent.com/leminkozey/help-book/main/scripts/install.sh | bash

This drops a ready-to-edit help/ folder next to where you ran it (with starter chapters.json + one demo chapter). Then serve it with any static file server:

cd help && python3 -m http.server 8082

python3 -m http.server is for local development only — not production-ready (single-threaded, no TLS, no security headers). For production use nginx, Caddy, or a CDN.

Or with Express:

app.use('/help', express.static('help', {
  dotfiles: 'deny',
  redirect: false,
  index: 'index.html'
}));

Updating

After the first install, every help/ folder comes with its own updater:

bash help/update          # → latest release
bash help/update v2.5.0   # → pin a specific version

The wrapper resolves the target relative to itself, so it works regardless of the directory you run it from. Your chapters.json and everything under chapters/ is never touched — only the bundled code files are replaced.

Before overwriting anything, the previous code files are copied to help/.help-book-backup/. If the new release breaks something, roll back with:

cp help/.help-book-backup/*.* help/
cp help/.help-book-backup/update help/ 2>/dev/null

Install Options

# Pin a specific version
curl -fsSL https://raw.githubusercontent.com/leminkozey/help-book/main/scripts/install.sh | bash -s v2.5.0

# Custom target directory (default: ./help)
HELP_BOOK_DIR=public/docs curl -fsSL https://raw.githubusercontent.com/leminkozey/help-book/main/scripts/install.sh | bash

The installer:

Prefer to inspect first? curl -fsSL .../install.sh -o install.sh && less install.sh && bash install.sh

Manual download

If you don’t want to run a remote script, grab the ZIP for the latest release:

TAG=$(curl -fsSL https://api.github.com/repos/leminkozey/help-book/releases/latest \
      | grep -m1 '"tag_name"' | cut -d'"' -f4)
curl -LO "https://github.com/leminkozey/help-book/releases/download/$TAG/help-book-$TAG.zip"
unzip -n "help-book-$TAG.zip" -d help/   # -n: never overwrite existing files

Or pin a specific version manually from the releases page — the asset is always named help-book-vX.Y.Z.zip.

The ZIP contains only the five code files (index.html, help.css, help.js, logo.svg, update). Your chapters.json and anything in chapters/ is never overwritten — unzip -n is belt-and-suspenders against future archive changes.

Final layout

your-project/
  help/
    index.html       # ← managed by installer
    help.css         # ← managed by installer
    help.js          # ← managed by installer
    logo.svg         # ← managed by installer
    update           # ← managed by installer (run with: bash help/update)
    chapters.json    # ← yours: edit freely
    chapters/        # ← yours: edit freely
      01-getting-started.md

Configuration

Everything is configured in chapters.json:

{
  "title": "My Project Help",
  "version": "v1.0.0",
  "accent": "#e8791d",
  "chapters": [
    {
      "id": "intro",
      "title": "Introduction",
      "file": "chapters/01-intro.md"
    },
    {
      "id": "advanced",
      "title": "Advanced",
      "children": [
        {
          "id": "plugins",
          "title": "Plugins",
          "file": "chapters/02-advanced/01-plugins.md"
        }
      ]
    }
  ]
}
Property Description
title Header and browser tab title
version Shown in footer (optional)
accent CSS accent color — accepts hex, rgb(...), hsl(...), oklch(...) (default: warm orange #e8791d)
editUrl Optional URL template for an “Edit this page on GitHub” link rendered under each chapter. Use {file} as a placeholder for the chapter’s file value, e.g. https://github.com/you/repo/edit/main/help/{file}. Omit the key to hide the link.
chapters Ordered list of chapter objects

Chapters can be nested one level deep. Parent chapters can optionally have their own file.

Embedding Images

Images work the same way they do in regular Markdown — drop a file somewhere reachable by the static server and reference it from your chapter:

![Sidebar in dark mode](images/sidebar-dark.png)

If you need more control over sizing, fall back to a raw <img> tag:

<img src="images/sidebar-dark.png" alt="Sidebar in dark mode" width="600">

The suggested layout is a per-chapters images/ folder, referenced relative to the chapter file:

help/
  chapters/
    01-getting-started.md
    images/
      sidebar-dark.png

External URLs (https://...) work too, as long as the host allows hot-linking and your CSP permits the image source.

A note on sanitization: Markdown is rendered through marked and then scrubbed by DOMPurify. For <img> only a small set of attributes survives — src, alt, title, width, height. Event handlers (onerror, onload, …) and anything else get stripped. That’s intentional, not a bug: it’s what keeps user-supplied Markdown safe to render.

Theming

Override CSS variables in help.css for deeper customization:

:root {
  --help-accent: #3b82f6;
  --help-bg: #f5f5f7;
  --help-card-bg: #ffffff;
  --help-sidebar-w: 280px;
}

Dark mode follows the user’s prefers-color-scheme by default. The user’s manual choice is stored in localStorage and synced across tabs via the storage event. When storage is cleared, the system preference takes over again.

Security

The library renders user-supplied Markdown — sanitization is critical. Built-in protections:

For production deployments, set these HTTP headers via your reverse proxy:

X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
Referrer-Policy: no-referrer
Content-Security-Policy: default-src 'none'; script-src 'self' https://cdnjs.cloudflare.com https://cdn.jsdelivr.net 'unsafe-inline'; style-src 'self' https://cdnjs.cloudflare.com https://fonts.googleapis.com 'unsafe-inline'; img-src 'self' data:; connect-src 'self'; font-src 'self' data: https://fonts.gstatic.com; base-uri 'none'; form-action 'none'; frame-ancestors 'self'

Avoid symlinks inside help/ — static servers may follow them and leak files outside the directory.

Requirements

Releases

Versioned via SemVer. Tagging a v*.*.* triggers a GitHub Action that generates CHANGELOG.md entries from Conventional Commits and creates a GitHub Release. See CHANGELOG.md for the full history.

License

MIT — see CHANGELOG.md for what changed in each version.