Skip to content
| Marketplace
Sign in
Visual Studio Code>Other>Four Markdown ViewerNew to Visual Studio Code? Get it now.
Four Markdown Viewer

Four Markdown Viewer

Four

|
2 installs
| (0) | Free
Side-by-side Markdown preview with light/dark themes, Mermaid and Excalidraw diagrams.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

Markdown Viewer

Side-by-side Markdown and MDX preview for VS Code. Follows the editor's light/dark theme and renders Mermaid and Excalidraw diagrams. Vocabulary is in GLOSSARY.md.

Use

Run Markdown Viewer: Open Preview to the Side (command palette or the editor-title button on .md/.mdx). No default keybinding; bind markdownViewer.openToSide yourself.

Run Markdown Viewer: Preview Active Tab to open a Preview that follows the active text tab: switching to another tab (any language: .txt, untitled buffer, the modified side of a diff) re-targets it, and non-text tabs (images, webviews, notebooks) are ignored. Content is rendered as Markdown. There is one following Preview; "Open Preview to the Side" Previews stay locked to their document. After a window reload a following Preview comes back locked to its last document.

Syntax

  • ```mermaid fence: Mermaid diagram (securityLevel: strict).
  • ```excalidraw fence: inline Excalidraw scene JSON, drawn read-only.
  • ![alt](https://github.com/iamnumberfourrrr/vscode-markdown-viewer/raw/HEAD/path/to/scene.excalidraw) or .excalidraw.json: linked scene, refreshed when the file changes. Paths must stay inside a workspace folder or the document's folder.
  • Excalidraw diagrams can be zoomed and panned: Ctrl/Cmd + wheel (or a trackpad pinch) zooms toward the cursor, dragging pans, the + / - / 0 keys zoom and reset, and a double-click resets. Zooming, panning and the keyboard never show controls by themselves. While a diagram is zoomed, moving the pointer over it shows − / percentage / + buttons in its corner (the percentage button resets); they hide again after 2 seconds without pointer movement and stay put while the pointer rests on a button. At 100% there are no controls. Plain scrolling still scrolls the Preview, and a click on a diagram link still works unless it was a drag.
  • MDX: import/export are hidden and {expr} is shown as text. A JSX element renders only the content between its tags (no <Name> label), with a UI | JSX tab to switch to its source. Components are never executed, so a self-closing element shows no content.

Caching

Rendered Mermaid and Excalidraw SVGs, syntax-highlighted code tokens and parsed documents are cached in the Preview, so returning to a document (or re-rendering after a theme change back) skips the expensive work. Entries expire after 10 minutes without use (CACHE_TTL_MS in src/webview/cache.ts, a sliding TTL) and each cache is size-bounded, evicting the least recently used. Linked Scenes are cached by their content, so an edited scene file is never served stale. Switching documents in the following Preview keeps the webview (and its caches) alive while both documents live under the same workspace folders; a document outside every workspace folder needs different file-access roots, so the Preview reloads and its caches start empty.

Security model

The extension is enabled in Restricted Mode and renders untrusted documents, so:

  • No author code runs. Raw HTML is sanitized (no scripts, iframes, forms, styles or event handlers), MDX components and import/export are never executed, Mermaid runs with securityLevel: strict, and Excalidraw scenes are drawn as static SVG.
  • Strict CSP. Scripts need a per-load nonce and may only load from the extension's own dist/webview folder; fetch is limited to the same folder. Workspace files can be shown as images or fonts but never executed or fetched by script.
  • File access stays inside the workspace. Linked scenes, images and links are resolved against the real path (symlinks are followed before the check), so a link can only reach workspace folders or the document's own folder. Only files on disk are supported (virtualWorkspaces: false).
  • Links go through the host. Markdown links and diagram links (Excalidraw and Mermaid) are limited to http(s): and mailto: and are opened by the extension; other schemes, such as vscode:, are dropped.
  • Limits protect the Preview. A single block over 100,000 characters (a very large table, for example) is shown as source text, a document over 5,000,000 characters is not parsed, and Excalidraw scenes over 20 MB, 5,000 elements or 50,000 px per element are rejected with an error card.
  • Restored Previews are allowlisted. After a window reload only documents you explicitly previewed are restored; the saved webview state is not trusted.

Develop

npm install
npm run build        # dist/extension.js + dist/webview/
npm run typecheck

Press F5 (.vscode/launch.json) to start an Extension Development Host on fixtures/; open any fixture and run the command. Package with npm run package (VSIX only).

Releasing

Publishing runs from .github/workflows/publish.yml with Marketplace Trusted Publishing (no stored token).

  1. Bump version in package.json, merge to main.
  2. Push a matching tag from main: git tag v<version> && git push origin v<version>. The workflow fails if the tag and package.json disagree or the commit is not on main.
  3. The build job installs with --ignore-scripts, builds and packages the VSIX with no publish credentials. The publish job runs in the marketplace Environment (only v* tags may deploy), downloads the VSIX and runs a version-pinned vsce publish --oidc.

The Trusted Publishing policy on the Marketplace publisher page must list owner iamnumberfourrrr, repository vscode-markdown-viewer, workflow publish.yml and environment marketplace. A manual run from main only verifies the build; it does not publish.

Known limitations

  • Excalidraw CJK text falls back to system fonts (the ~13 MB Xiaolai font is not bundled).
  • Excalidraw tries esm.sh as a font fallback URL; the webview CSP blocks it, so nothing leaves the machine, but the console shows blocked requests.
  • Caches live in the Preview's webview and are dropped when it is closed or reloaded (including a window reload); they are not persisted.
  • Blocks over 100,000 characters render as source text instead of formatted Markdown.
  • No automated tests: verification is manual against fixtures/.
  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
  • Your Privacy Choices
  • Consumer Health Privacy
© 2026 Microsoft