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.1.tar.gz (172.0 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.1-py3-none-any.whl (138.5 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: markdraft-1.0.1.tar.gz
  • Upload date:
  • Size: 172.0 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.1.tar.gz
Algorithm Hash digest
SHA256 6a0dd12f83c3392d7ddf6d6d4959621e9d7770f84759ce6296eaa6c343dac158
MD5 ef0db01180761ab9edf4227a8777afeb
BLAKE2b-256 64688bd2fd3baacb73a7e2a7a4fa2b299095ad97e48cd3e87f840ed3a667bf76

See more details on using hashes here.

Provenance

The following attestation bundles were made for markdraft-1.0.1.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.1-py3-none-any.whl.

File metadata

  • Download URL: markdraft-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 138.5 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.1-py3-none-any.whl
Algorithm Hash digest
SHA256 18b6202b3c3b50e6c157c51d9a763402edc7c98db39648f008d91f425e5a2865
MD5 6f85c57d09c8320fcc337a04670554fe
BLAKE2b-256 38ecd3e1378169818bbe7bd10aad1a6686a341a2ecf7350bfe63e1f4ce044567

See more details on using hashes here.

Provenance

The following attestation bundles were made for markdraft-1.0.1-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