Skip to main content

Preview local markdown files with mermaid diagram support.

Project description

Markdraft

Preview local markdown files in the browser with GitHub-flavored rendering, mermaid diagrams, math, syntax highlighting, and live reload. Zero runtime dependencies.

$ draft README.md
 * Serving on http://localhost:6419/

Installation

From PyPI

pip install markdraft

Or with uv:

uv tool install markdraft

Standalone executable

Download markdraft.pyz from Releases and run it directly — no installation needed:

python markdraft.pyz README.md

Requires Python 3.10+. On first run, markdraft downloads about 3.5 MB of JavaScript libraries from jsDelivr and caches them in ~/.markdraft/.

Usage

Preview a file:

$ draft README.md
 * Serving on http://localhost:6419/

Preview a directory (serves its README.md):

$ draft .

Open the browser automatically:

$ draft -b README.md

Specify host and port:

$ draft README.md 0.0.0.0:8080

Export to a self-contained HTML file:

$ draft --export README.md
Exporting to README.html

Export with CDN links instead of inlined assets:

$ draft --export --no-inline README.md

Dark mode:

$ draft --theme=dark README.md

The mdraft command is also available as an alias, for environments where draft conflicts with Azure Draft.

Features

  • Live reload — file changes are detected and the browser refreshes automatically via Server-Sent Events
  • Mermaid diagrams```mermaid fenced code blocks rendered by mermaid.js
  • Math/LaTeX$inline$ and $$display$$ math rendered by KaTeX
  • Syntax highlighting — code blocks highlighted by highlight.js
  • GitHub Alerts> [!NOTE], > [!TIP], > [!IMPORTANT], > [!WARNING], > [!CAUTION] styled callout boxes
  • GeoJSON maps```geojson and ```topojson rendered as interactive maps by Leaflet
  • STL 3D models```stl rendered as rotating 3D views by Three.js
  • Task lists- [x] and - [ ] checkboxes
  • Emoji shortcodes:rocket: → :rocket:, full gemoji set (1,800+ shortcodes)
  • GitHub styling — rendered with github-markdown-css
  • Export — self-contained HTML files with all assets inlined or linked via CDN
  • Zero dependencies — no pip runtime dependencies; rendering is done client-side by cached JavaScript libraries
  • Auto/dark/light mode — follows OS preference by default (--theme=auto), or force with --theme=dark / --theme=light
  • Standalone executable — download a single .pyz file, no installation required

Rendering Showcase

The examples below exercise every client-side rendering feature. Running draft README.md and checking that each one renders correctly is a quick smoke test for a new installation.

Syntax highlighting

def fibonacci(n: int) -> int:
    a, b = 0, 1
    for _ in range(n):
        a, b = b, a + b
    return a

Mermaid diagrams

graph LR
    A[Markdown file] --> B[HTTP Server]
    B --> C[Browser]
    C --> D[marked.js]
    D --> E[Rendered HTML]

Math / LaTeX

Euler's identity: $e^{i\pi} + 1 = 0$

The Gaussian integral:

$$\int_{-\infty}^{\infty} e^{-x^2} , dx = \sqrt{\pi}$$

GitHub Alerts

[!NOTE] This is a note — useful for supplementary information.

[!TIP] This is a tip — helpful advice for the reader.

[!IMPORTANT] This is important — key information the reader should know.

[!WARNING] This is a warning — something that could cause problems.

[!CAUTION] This is a caution — potential for data loss or security risk.

GeoJSON maps

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "geometry": {
        "type": "Polygon",
        "coordinates": [[
          [-122.42, 37.78], [-122.42, 37.77], [-122.41, 37.77],
          [-122.41, 37.78], [-122.42, 37.78]
        ]]
      },
      "properties": { "name": "San Francisco" }
    }
  ]
}

Emoji shortcodes

:rocket: :sparkles: :warning: :bug: :white_check_mark: :x: :heart: :star: :fire: :eyes: :tada: :construction:

Task lists

  • Syntax highlighting
  • Mermaid diagrams
  • Math / LaTeX
  • GitHub Alerts
  • GeoJSON maps
  • Task lists
  • Emoji shortcodes

Tables

Library Purpose Size
marked.js Markdown rendering 40 KB
highlight.js Syntax highlighting 40 KB
KaTeX Math rendering 270 KB
mermaid.js Diagrams 2.9 MB

CLI Reference

usage: draft [-h] [-V] [--user-content] [--wide] [--clear] [--export]
             [--no-inline] [-b] [--title TITLE] [--norefresh] [--quiet]
             [--theme THEME]
             [path] [address]
Flag Description
path File or directory to render (- for stdin)
address host:port to listen on, or output file for --export
-b, --browser Open browser tab after server starts
--export Export to HTML file instead of serving
--no-inline Use CDN links instead of inlining assets in export
--title TITLE Override the page title
--theme THEME Color theme: auto (default), light, or dark
--user-content Render as GitHub issue/comment style
--wide Wide layout (with --user-content)
--norefresh Disable auto-refresh on file change
--quiet Suppress terminal output
--clear Clear the cached assets and exit
-V Show version and exit

Python API

from markdraft import serve, export, clear_cache

# Start a preview server
serve("README.md", port=8080, browser=True)

# Export to HTML
export("README.md", out_filename="preview.html")

# Clear cached CDN assets
clear_cache()

Configuration

Create ~/.markdraft/settings.py to override defaults:

HOST = "0.0.0.0"
PORT = 8080
AUTOREFRESH = True
QUIET = False

The MARKDRAFT_HOME environment variable overrides the config directory (default ~/.markdraft).

Architecture

Markdraft is a thin HTTP server built on Python's http.server. It serves raw markdown via a JSON API and lets the browser handle all rendering:

sequenceDiagram
    participant B as Browser
    participant S as Server (http.server)
    B->>S: GET /
    S-->>B: HTML shell (template + script tags)
    B->>S: GET /__/api/content
    S-->>B: raw markdown as JSON
    Note over B: marked.js renders markdown
    Note over B: KaTeX renders math
    Note over B: highlight.js highlights code
    Note over B: mermaid.js renders diagrams
    B->>S: GET /__/api/refresh (SSE)
    S-->>B: file change notifications

Modules:

Module Purpose
markdraft/server.py HTTP server with routing
markdraft/readers.py File/directory/stdin reading
markdraft/assets.py CDN asset downloading and caching
markdraft/export.py Self-contained HTML export
markdraft/watcher.py File change detection for auto-refresh
markdraft/browser.py Browser tab opening
markdraft/config.py Constants, CDN URLs, settings loader
markdraft/command.py CLI argument parsing

Development

git clone https://github.com/imofftoseethewizard/markdraft
cd markdraft
uv sync
uv run pytest              # 148 tests, ~8s parallel
uv run pyright markdraft/  # type checking
uv run black markdraft/ tests/  # formatting

Acknowledgments

Markdraft began as a fork of Grip by Joe Esposito. Grip is a well-crafted tool for previewing GitHub-flavored markdown locally, and its reader abstractions and CLI design informed markdraft's architecture.

Major changes from Grip

  • Zero runtime dependencies — Grip depends on Flask, Markdown, Pygments, requests, docopt, path-and-address, and Werkzeug. Markdraft has no pip dependencies; it uses only the Python standard library.
  • Client-side rendering — Grip renders markdown server-side with Python. Markdraft serves raw markdown and renders it in the browser with marked.js, highlight.js, and mermaid.js.
  • Math/LaTeX support$inline$ and $$display$$ math via KaTeX.
  • GitHub Alerts> [!NOTE], > [!WARNING], etc. rendered as styled callout boxes.
  • Mermaid diagram support```mermaid fenced code blocks rendered as diagrams.
  • GeoJSON maps and STL 3D models — interactive maps via Leaflet, rotating 3D model views via Three.js.
  • stdlib HTTP server — replaces Flask with http.server.ThreadingHTTPServer.
  • Modern Python — requires Python 3.10+, full type annotations, no Python 2 compatibility code.
  • uv project managementpyproject.toml with hatchling build backend, managed by uv.
  • Security hardening — path traversal protection via Path.relative_to(), symlink escape prevention, case-insensitive </script> escaping in exports.
  • Standalone executable — downloadable .pyz file, no installation required.
  • GitHub API removed — Grip's primary mode was to POST markdown to the GitHub API for rendering. Markdraft renders entirely offline.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

markdraft-1.0.3.tar.gz (172.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

markdraft-1.0.3-py3-none-any.whl (139.3 kB view details)

Uploaded Python 3

File details

Details for the file markdraft-1.0.3.tar.gz.

File metadata

  • Download URL: markdraft-1.0.3.tar.gz
  • Upload date:
  • Size: 172.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for markdraft-1.0.3.tar.gz
Algorithm Hash digest
SHA256 73127e5620e0417f240e3751df2c8c4bc4e83a6cb4782e4bd31a11277e4eba1d
MD5 83c10b081cc4dc83f12e7facc7d0dd41
BLAKE2b-256 de306944a441518e340a35e08c0466eba3af2aaf4da66aa9136580197dc81f1c

See more details on using hashes here.

Provenance

The following attestation bundles were made for markdraft-1.0.3.tar.gz:

Publisher: release.yml on imofftoseethewizard/markdraft

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file markdraft-1.0.3-py3-none-any.whl.

File metadata

  • Download URL: markdraft-1.0.3-py3-none-any.whl
  • Upload date:
  • Size: 139.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for markdraft-1.0.3-py3-none-any.whl
Algorithm Hash digest
SHA256 22b8dbe2c13c56984d3340a555b88d4180866665c07856349de760f8dc75fa3a
MD5 0bf4900c47e57f116c91053d73535413
BLAKE2b-256 87aa0655f5cadc8de20a1e20a288ca6916d59f2215fa49ca743b8be7b7e93648

See more details on using hashes here.

Provenance

The following attestation bundles were made for markdraft-1.0.3-py3-none-any.whl:

Publisher: release.yml on imofftoseethewizard/markdraft

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page