Skip to content

About

A fast, private, browser-only markdown editor with live preview, math, and Mermaid diagrams.

Topics

Resources

Contributing

Security policy

Stars

3 stars

Watchers

0 watching

Forks

Latest commit

 

History

101 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

mdfor.dev

CI License: MIT Live site

A fast, private markdown editor with live preview that runs entirely in your browser. No accounts, no backend, no tracking: your writing never leaves your device.

Try it at mdfor.dev. (mdfor.work redirects there.)

mdfordev-promo.mp4

Contents

Why mdfor.dev

  • Private by design. Everything happens client-side. Content and settings are stored only in your browser's localStorage.
  • Fast to open. No UI framework, and heavy renderers (syntax highlighting, math, diagrams) load only when your document needs them.
  • Works offline. After one visit, the app opens without a network connection, including the renderers you've already used.
  • Self-contained. Scripts, styles, and fonts are bundled and served from the same origin. No third-party CDNs.

Features

Writing

  • Live preview as you type, with GitHub Flavored Markdown and line breaks preserved
  • Line-number gutter and optional scroll sync between editor and preview
  • Built-in markdown linting with a clickable panel that jumps to the offending line
  • Auto-save of your document and preferences (theme, pane width, collapsed editor, scroll sync, linting, remote image blocking)
  • Offline use through a service worker; when a new version is deployed, an Update available toast offers a reload instead of swapping code mid-edit
  • A rich starter document that shows off what the editor can render

Rendering

  • Syntax-highlighted code blocks via highlight.js, themed to match light or dark mode
  • Math with KaTeX and diagrams with Mermaid
  • YAML frontmatter at the top of a file shown as a small metadata table, like GitHub
  • Fullscreen viewer for images and diagrams
  • Optional blocking of remote images, with alt-text placeholders and a Load images button
  • Mermaid diagram toolbar to view full screen, copy as PNG, or download as PNG
  • All rendered HTML sanitized with DOMPurify

Import and export

  • Import .md, .markdown, or .txt files with the file picker or by dragging a file onto the editor (you're asked before your own content is replaced, but not the welcome document)
  • Open .md and .markdown files from your file manager (double-click or Open with) after installing the app in Chrome or Edge. This uses the File Handling API, which only Chromium browsers support. If the app is already open, the file opens in that window
  • Export as:
    • Markdown (.md) source
    • HTML: a self-contained file with embedded styles and optional base64-inlined images
    • PDF through the browser's print dialog (choose "Save as PDF")

Keyboard shortcuts

Use Cmd on macOS and Ctrl on Windows and Linux. Shortcuts are paused while a dialog is open.

Shortcut Action
Cmd/Ctrl+O Import a file
Cmd/Ctrl+S Download the document as .md
Cmd/Ctrl+\ Collapse or expand the editor (not available on mobile)

Layout

  • Resizable split panes (drag the handle, or focus it and use the arrow keys)
  • Collapsible editor for distraction-free reading
  • Document outline: a side panel listing the headings that jumps to a section and highlights the one you're reading (it slides over the preview on mobile)
  • Light and dark themes
  • Responsive layout with editor/preview tabs on mobile

Supported syntax

Everything in GitHub Flavored Markdown (tables, task lists, strikethrough, autolinks, fenced code), plus:

Inline math: $E = mc^2$

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

```mermaid
graph LR
  Write --> Preview --> Export
```

A claim that needs a source.[^1]

[^1]: Footnotes link to the note and back, as on GitHub.

Lint rules

Linting is off by default; turn it on from the header. The rules follow markdownlint numbering:

Rule Checks for
MD009 Trailing spaces
MD010 Hard tabs
MD012 Multiple consecutive blank lines
MD018 No space after # in a heading
MD022 Headings not surrounded by blank lines
MD037 Spaces inside emphasis or bold markers
MD041 First line isn't a top-level heading
MD047 File doesn't end with a newline

Privacy and security

  • Your markdown and settings stay on your device. Nothing is sent to a server.
  • The production site ships a strict Content Security Policy (see _headers): scripts, fonts, and network connections are limited to the same origin, and the app can't be embedded in frames.
  • Images referenced in your markdown by URL are fetched from those URLs by default, which reveals your IP address to their hosts. Turn on Block remote images in the header to stop this: remote images (including ones in raw HTML, inline styles, and Mermaid diagrams) show as placeholders with their alt text, and Load images loads them for the current document. Images from the same site and data: URLs always load.
  • If localStorage is unavailable (for example, in some private browsing modes), the app still works but won't remember your content or settings.

To report a vulnerability, see SECURITY.md.

Getting started

Prerequisites: Node.js 20.19+ (or 22.12+) and npm.

git clone https://github.com/ikhattab/md-preview.git
cd md-preview
npm install
npm run dev      # Vite dev server at http://localhost:5173

For a production-like preview:

npm run build
npm run preview  # serves ./dist at http://localhost:3000 with the headers from _headers

Scripts

Command Description
npm run dev Vite dev server with hot reload
npm run build Production build to dist/
npm run preview Serve the production build on port 3000
npm run lint Run ESLint
npm run lint:fix Run ESLint with autofix
npm run format Format all files with Prettier
npm run format:check Check formatting with Prettier
npm run check Lint and format check (CI runs this, then the build)
npm run test:e2e Playwright smoke tests against the production build

Deployment

Pushes to main deploy automatically to Cloudflare Pages (the md-preview project), served at mdfor.dev:

  • Build command: npm run build
  • Output directory: dist

The output is a plain static site, so any static host works (Netlify, S3, nginx, and so on): run npm run build and serve dist/. _headers sets long-lived caching for hashed assets and the Content Security Policy on hosts that support that file format; on other hosts, configure the equivalent headers yourself. Serve /sw.js with Cache-Control: no-cache (not the long-lived rules), or returning users won't see new versions promptly.

Architecture

Plain HTML, CSS, and ES modules, bundled and code-split by Vite. Markdown is parsed by marked with marked-highlight and marked-katex-extension; icons come from Lucide, and fonts are self-hosted via Fontsource.

Project structure
Path Purpose
index.html Layout and entry point
app.js Initialization and event wiring
styles.css Theming, layout, and responsive styles
lib/constants.js Shared constants and the starter document
lib/dom.js DOM element references
lib/storage.js localStorage helpers
lib/utils.js Debounce, throttle, and string helpers
lib/preview.js Markdown parsing, sanitization, Mermaid, preview updates
lib/preview-blocks.js Updates only the preview blocks that changed
lib/frontmatter.js YAML frontmatter detection and metadata table
lib/gutter.js Line-number gutter
lib/lint.js Lint rules and panel UI
lib/theme.js Theme loading and toggling
lib/layout.js Resize, collapse, mobile view, scroll sync
lib/header-menu.js Mobile overflow menu for the header controls
lib/content.js Auto-save and content loading
lib/import-export.js Import and Markdown/HTML/PDF export
lib/file-launch.js Opens files the OS launches the installed app with
lib/lazy-vendors.js Lazy loading for highlight.js, KaTeX, and Mermaid
lib/offline.js Service worker registration and the update prompt
lib/outline.js Document outline side panel
lib/media-viewer.js Fullscreen image and diagram viewer
lib/remote-images.js Remote image blocking and placeholders
lib/icons.js Lucide icon helpers
lib/tooltip.js Viewport-aware tooltips
lib/fonts.js Self-hosted font imports
sw.js Service worker for offline use
vite.config.js Build configuration
scripts/cloudflare-headers.js Applies _headers in vite preview
scripts/service-worker.js Emits sw.js with the build's file lists
scripts/og-image.html Source page for the social preview image
_headers Cache and security headers for static hosting
site.webmanifest Web app manifest

Contributing

Contributions are welcome. Read CONTRIBUTING.md for setup and guidelines. In short: keep the app private (no network requests or CDNs), lazy-load anything heavy, sanitize rendered HTML, and run npm run check && npm run build before opening a pull request. CI runs the same checks on every PR.

Found a bug or have an idea? Open an issue.

License

MIT © Ihab Khattab

About

A fast, private, browser-only markdown editor with live preview, math, and Mermaid diagrams.

Topics

Resources

Contributing

Security policy

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages