# Markdown Viewer: a local-first editor that renders everything in the browser

> Markdown Viewer is a static, client-side workspace for `.md` files with live preview, an extensive diagram and math renderer set, anchored review comments, and delivery as a hosted app, a PWA, a Docker image or a Neutralino desktop build. It suits writers and developers who want documents to stay on their own machine, and it is not a collaborative editor with a server behind it.

**ThisIs-Developer/Markdown-Viewer** — A Markdown Editor That Lives in Your Browser, Desktop, and a Single URL. Fast GitHub-style Markdown editing with live preview, diagrams, LaTeX, syntax highlighting, PDF export, and multi-tab support across web, desktop, and Docker.

- Repository: https://github.com/ThisIs-Developer/Markdown-Viewer
- Website: https://markdownviewer.pages.dev
- Stars: 551 · Forks: 132
- Language: JavaScript
- License: Apache-2.0
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/thisis-developer-markdown-viewer

## Local-first, with the data in IndexedDB and no account

Markdown Viewer is described as a local-first Markdown editor and viewer with live preview, and the README is explicit about the data boundary. Everyday editing stays on your device, no account is required, and the application includes no ads, analytics, telemetry or subscriptions.

The storage model is visible in the feature list. On the web, each document is kept in per-document IndexedDB storage, with a Recent list, Favorites, search, tabs and bulk actions. There is a 30-day Trash for recoverable normal and encrypted files, and an encrypted Secret Workspace. A middle click on a tab closes it without deleting the saved document, which is a small detail that tells you the state model is more careful than a typical text editor.

The workspace is exportable as a folder-preserving ZIP. Encrypted Secret Workspace files are optional in that backup, and the trash and the desktop history stay outside it, so the archive is a copy of your documents rather than a snapshot of the application.

The audience is broad, and the README says so without qualification: developers, writers, students, researchers, and anyone working with `.md` or `.markdown` files. The word local-first is doing real work in that sentence. It means the editor is usable with the network unplugged, and it means the review features, such as anchored comments with threaded replies that do not change the Markdown, are comments stored alongside the document rather than comments written into it.

The project is licensed Apache-2.0, with a `LICENSE` file in the repository.

## The renderer set is the reason the project exists

Most Markdown viewers render Markdown. This one renders a catalogue of things, and the list is long enough to be the differentiator.

For Markdown itself the support is CommonMark-style Markdown, GitHub-Flavored Markdown, tables, task lists, alerts, footnotes, definition lists, syntax highlighting, sanitized HTML and MathJax. Sanitized HTML matters here, since raw HTML in a document is a script injection risk in any viewer that accepts untrusted files.

The visual content list is where the project goes further. The README names Mermaid, PlantUML, Graphviz/DOT, D2, Vega-Lite, WaveDrom, Markmap, GeoJSON, TopoJSON, STL and ABC notation. That is eleven distinct renderers covering flowcharts, UML, graph description languages, statistical charts, timing diagrams, mind maps, geographic data, 3D models and music notation, all inside the same preview pane.

A Document Outline panel is opened from a book-text button and gives a resizable right sidebar with collapsible heading branches, a Collapse or Expand All control and section navigation, working in Editor, Preview and Split modes. It can copy a GitHub-compatible Markdown table of contents with configurable heading depth, bulleted or numbered links or plain text, optional level normalization and a collapsible wrapper.

The dependency list backs the rendering claims. The project pins `marked` at 9.1.6 for parsing, `dompurify` at 3.4.13 for sanitizing, `highlight.js` and `@highlightjs/cdn-assets` at 11.9.0 for syntax highlighting, `mathjax` at 4.0.0-beta.7 with matching Asana and STIX2 font packages, `github-slugger` for anchor generation, `github-markdown-css` for the rendered look, `jszip` for the workspace archive, `file-saver` for downloads, `emoji-toolkit` for emoji, and `js-yaml` for front matter handling.

## Running it locally, and why file:// will not work

The Quick Start section gives one path for local use, and it is worth following exactly rather than improvising.

```bash
git clone https://github.com/ThisIs-Developer/Markdown-Viewer.git
cd Markdown-Viewer
python -m http.server 8080
```

Then open `http://localhost:8080`. The README is emphatic about the next point: do not rely on `file://`, because browser security rules can block Web Workers and Service Workers. That is a real functional constraint rather than a style note, since the repository contains `sw.js`, `preview-worker.js`, a `workers/` directory and `workspace-storage.js`, and those are exactly the pieces that a `file://` origin would refuse to run.

The delivery options are broader than a single local server. The README lists the hosted web app, installing the PWA, self-hosting static files, running Docker, deploying on Cloudflare, and building the Neutralino desktop application. A `Dockerfile` and `docker-compose.yml` are in the tree, and the `desktop-app/` directory covers the Neutralino route.

The container is a plain static file server. The Dockerfile uses `nginx:alpine` as the base, copies a specific list of files into `/usr/share/nginx/html/` rather than the whole context, and adds an nginx configuration with gzip for text assets, a cache rule giving static assets a one year expiry with a public immutable cache control header, client-side routing through `try_files` so the single page app resolves deep links, and security headers including `X-Frame-Options SAMEORIGIN` and `X-Content-Type-Options nosniff`. The compose file publishes port 8080 on the host mapped to port 80 in the container, with a `restart: unless-stopped` policy and `NGINX_HOST` and `NGINX_PORT` environment variables.

## Editing, reviewing and exporting in the same workspace

The editing surface has three layouts: Editor, Split view and Preview. Typing `/` at the start of a line opens searchable block commands, and the formatting tools, an 8x8 quick table selector, productivity shortcuts, custom undo and redo, Find and Replace, LTR and RTL direction support, smooth Page Up and Page Down navigation, pane-scoped Select All, rich Preview copying and selection-anchored comments with threaded replies are all part of the same window rather than separate tools.

Comments are anchored to a selection and do not change the Markdown, which is what makes review different from editing. A colleague can leave a note about a paragraph without a stray `<!-- -->` block ending up in the file, and the note lives in the local storage model.

Import and export cover a wide range. You can open local files or pull content from GitHub branches, tags, commit SHAs, and optionally private repositories. You can export Markdown, standalone HTML, PNG, Browser Print or Save as PDF, or a legacy raster PDF with remembered Light or Dark appearance and complete rich-content preparation for the PDF and PNG paths.

Sharing is deliberately optional and comes in two forms. A Share Snapshot turns a document into a link with View only or Can edit access for quick handoffs, and a temporary Live Share room supports host, Can edit and View only capabilities with live cursors, anchored comments and threaded replies. The first is a link to a snapshot. The second is a real-time session, and the wording in the README points to the Live Share mechanism rather than to a collaboration server the project operates.

The repository also carries a `functions/` directory and `wrangler.toml` and `wrangler.live-room.toml`, which is consistent with a Cloudflare Workers deployment for the pieces that need a server.

## The build and test scripts are the real documentation

The `package.json` describes the project as development and automated testing tools for Markdown Viewer, is marked private, and is at version 3.10.4, which matches the newest release tag. It requires Node 22 or later, with the range given as `>=22 <27`.

The scripts are worth reading, because they tell you what the maintainers consider the quality gates. `build` runs `build:toc`, then `check:static`, then `check:seo`, and `build:toc` executes `scripts/build-document-toc.mjs` to generate the table of contents. `check:static` runs `tests/helpers/static-build-check.mjs` and `check:seo` runs the sitemap generator in check mode. There is also `audit:seo` and `seo:sitemap`.

The test story is two-layered. `test` runs the build, then the unit tests, then the end-to-end tests. The unit tests run with the Node test runner over `tests/unit/*.test.mjs`, and the end-to-end tests use Playwright, with `test:install` installing chromium, firefox and webkit, and the default project being chromium. There are dedicated variants for a smoke spec, cross-browser runs, a UI mode, a headed mode, and `test:e2e:report` to open the Playwright report. The `playwright.config.js` file and the `tests/` directory in the tree confirm that the browser tests are a first-class part of the workflow.

The `start` and `dev` scripts both point at `node tests/helpers/static-server.mjs`, so the development server is the same static server used by the tests. The `.nvmrc` file pins a Node version for contributors, and the `seo/`, `scripts/`, `workers/`, `locales/` and `wiki/` directories show that the documentation, the search engine metadata and the worker code are all part of the same repository rather than separate projects.

## Localisation, limits and where the project stops

The application ships in more than one language in a way that goes beyond a translated interface. The README says any of 15 language URLs can be opened with translated initial content and a localized starter document before JavaScript runs, and that changing the interface language preserves user-authored Markdown and the Preview typography. The `locales/` directory holds per-language README files in Japanese, Korean, Simplified Chinese and Traditional Chinese, and the Docker image copies `seo/locales.mjs` and `seo/welcome-content.mjs` into the served directory.

The README also points to a feature reference at `wiki/Features.md` for verified behavior, limits and implementation notes, and to a `wiki/Home.md` as the documentation entry point. There is a `SECURITY.md`, a `CODE_OF_CONDUCT.md`, a `CONTRIBUTING.md` and a `CHANGELOG.md` plus a `RELEASE_NOTES` file.

The boundary of the project is worth being honest about. This is a client-side application, and the features that need a server are the ones with server-adjacent infrastructure behind them: the `functions/` directory and the Wrangler configuration exist because some part of it is deployed as serverless functions, and Live Share relies on a Live Share host. A reader who wants a self-hosted collaborative editor with its own accounts and persistent history will not find that here.

The other limitation is simply that a browser application is a browser application. The rendering of eleven formats, the encryption of the Secret Workspace, the PDF export path and the 3D model viewer all execute on the client, so the memory and CPU budget of the machine doing the writing is the budget you have. The Dockerfile's decision to serve only a curated list of files rather than the whole repository is a small admission of the same point.

## Maintenance pace and the cost of the dependency set

The project is moving quickly. Version 3.10.4 was released on 2026-10-09, 3.10.3 on 2026-09-27, 3.10.2 on 2026-09-03, and the last push to the default branch was on 2026-10-20. The repository is not archived.

That pace has a cost, and the `package.json` shows it. The dependencies are pinned to exact versions with no ranges: `dompurify` at 3.4.13, `marked` at 9.1.6, `highlight.js` at 11.9.0, `mathjax` at 4.0.0-beta.7, `jszip` at 3.10.1, `file-saver` at 2.0.5, `js-yaml` at 4.3.1, `esbuild` at 0.25.12, `bootstrap` at 5.3.2 and `emoji-toolkit` at 9.0.1. Notably, MathJax is on a beta version, and MathJax and its fonts move in lockstep, so a mismatch between the two MathJax packages and the renderer is a plausible source of a broken math preview after an update.

Because the application is a static bundle served by nginx, the dependency set only matters to people who build it. A user of the hosted app or the published container does not run npm at all, and for them the relevant question is whether the release they installed is the one you want. Given the release cadence, the reasonable practice is to pin a release tag rather than track the branch, and to read the `CHANGELOG.md` and `RELEASE_NOTES` files before upgrading, since a renderer change is exactly the kind of thing that alters output without an obvious signal.

The Apache-2.0 licence permits use, modification and redistribution with attribution and the patent grant, which is a reasonable basis for a tool you intend to self-host.

## Conclusion

Adopt Markdown Viewer when the work is single-machine writing and review of `.md` files, when privacy matters because no account, ads, analytics or telemetry are involved, and when the render set you need includes diagrams, math and syntax highlighting without assembling a build pipeline. Do not adopt it as a replacement for a multi-user collaborative platform, since the live sharing described in the README is built on Live Share rooms rather than a hosted backend of its own. Before you build on it, run the documented local server with `python -m http.server 8080` rather than opening `file://`, because browser security rules can block the Web Workers and Service Workers the application depends on, and check the `package.json` scripts, which require Node 22 or later and drive the Playwright end-to-end suite.

## FAQ

### How do I run Markdown Viewer locally?

Clone the repository, change into the `Markdown-Viewer` directory and serve it with `python -m http.server 8080`, then open `http://localhost:8080`. The README warns not to rely on `file://`, because browser security rules can block Web Workers and Service Workers.

### What diagram and visual formats can Markdown Viewer render?

The README lists Mermaid, PlantUML, Graphviz/DOT, D2, Vega-Lite, WaveDrom, Markmap, GeoJSON, TopoJSON, STL and ABC notation, alongside CommonMark-style and GitHub-Flavored Markdown, tables, task lists, alerts, footnotes, definition lists, syntax highlighting, sanitized HTML and MathJax.

### Does Markdown Viewer need an account or send my data anywhere?

No. The README states that everyday editing stays on your device, no account is required, and the application includes no ads, analytics, telemetry or subscriptions. On the web, documents are kept in per-document IndexedDB storage.

### Can I run Markdown Viewer with Docker?

Yes. A `Dockerfile` and `docker-compose.yml` are included. The image is based on `nginx:alpine` serving the static files on port 80, and the compose file maps host port 8080 to it, with a `restart: unless-stopped` policy and `NGINX_HOST` and `NGINX_PORT` environment variables.

### What do I need to build and test Markdown Viewer?

The `package.json` requires Node 22 or later, with the range given as `>=22 <27`. The build runs the table of contents generation, a static build check and an SEO check, unit tests run with the Node test runner, and end-to-end tests use Playwright, whose install step pulls chromium, firefox and webkit.

## Sources

- [License: Apache-2.0](https://github.com/ThisIs-Developer/Markdown-Viewer/blob/main/LICENSE)
- [Project website](https://markdownviewer.pages.dev)
- [README](https://github.com/ThisIs-Developer/Markdown-Viewer/blob/main/README.md)
- [Releases](https://github.com/ThisIs-Developer/Markdown-Viewer/releases)
- [ThisIs-Developer/Markdown-Viewer on GitHub](https://github.com/ThisIs-Developer/Markdown-Viewer)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/thisis-developer-markdown-viewer
