md for Visual Studio Code

Markdown with mathematics, chemistry, charts and diagrams — drawn entirely on
your own machine, inside the preview you already use.
What this is
md is a Markdown preview for people who write documents and not only
READMEs. Formulas and chemical equations, charts drawn from the function
you write, Mermaid flowcharts, Graphviz graphs, PlantUML drawings, data
pasted straight out of a spreadsheet, footnotes, front matter and
highlighted code all render as you type, and the finished document exports
to HTML, PDF, EPUB, LaTeX, TextBundle, TextPack or SVG.
The first thing worth knowing: it extends VS Code's built-in Markdown
preview rather than opening a window of its own. Open Preview
(⇧⌘V, Ctrl+Shift+V), Open Preview to the Side, the two-way scroll sync
and every keybinding you have already learned keep working exactly as
before, and one document renders the same way however you opened it.
Nothing asks you to lower markdown.preview.security either — the
extension is built around that strict default rather than around an
exception to it.
Everything is drawn on your own machine: by engine files carried inside the
extension, and, in the case of the charts, by the extension's own renderer.
There is no account, no server of ours and no network round trip.
Screenshots

A chart beside the formula that produced it, in a dark colour theme —
mathematics and chemistry set by KaTeX, and the chart drawn by the extension
itself, with no engine behind it. Its ink follows the theme, so the same fence
reads correctly light or dark.

The same document in a light theme. The page follows your colour theme and
your Markdown preview fonts by default.

A .puml file previewing as the diagram it describes, source still fully
editable, through Preview Diagram in the editor title bar.
Features
Mathematics, and chemistry with it
TeX and LaTeX mathematics inline as $…$, displayed as $$…$$, or in a
fenced ```math block, typeset by KaTeX. Chemical equations and physical
units come with it through the bundled mhchem extension: \ce{…} and
\pu{…} set the way a textbook would. A lone $ in prose is left alone,
so "$5 and $10" stays a sentence about money rather than becoming a
formula.
Charts, from a fence
A fenced ```plot block is a chart. Write sin(x) and you get the curve.
x: -10..10 sets the window and y: auto, which is the default, fits the
vertical axis to what the function actually does; title:, xlabel:,
ylabel:, legend:, grid:, axes:, width:, height: and samples:
set the rest. One figure holds as many series as you like, each drawn in its
own colour and named in the legend — envelope = exp(-abs(x)/5) — and a
series can equally be a parametric curve, (cos(t), sin(t)) for t in 0..2*pi, or measured numbers, points: 0,0 1,2 2,1. The expressions are
ordinary arithmetic and comparisons, the trigonometric, hyperbolic and
inverse functions, sqrt, cbrt, abs, exp, exp2, ln, log2,
log10, floor, ceil, round, atan2, pow and hypot, and the
constants pi and e.
Nothing is bundled to draw them. The diagram engines carried inside the
extension are megabytes of JavaScript apiece; a chart uses none of them. It
is drawn by the extension's own renderer, in the same pass that renders the
Markdown, so the engine files shipped here are exactly the files that were
there before charts existed. That is also what settles where a chart runs.
Graphviz is WebAssembly and has to be laid out in the extension host, where
it takes a moment to compile before the first graph appears; Mermaid and
PlantUML are scripts that run in the page itself. A chart is neither, so the
preview is handed a finished drawing rather than something that has to draw
one — nothing to fetch, nothing to warm up, nothing to fall back to, and no
script in the page for the preview's default security to allow or refuse.
Being a drawing from the outset is also why a chart survives the trip out of
the document. It is vector in the preview, in the self-contained HTML, in
the PDF and in an exported EPUB — the first vector figure md has put into a
book on any of its platforms, where every other rich block is a picture —
and Export Diagram as SVG… offers it beside the diagrams. LaTeX is the
exception: a .tex file cannot take a vector drawing without a conversion
step it has no way to carry, so a chart travels there as the source you
wrote, under a comment, exactly as a Mermaid, Graphviz or PlantUML block
does.
A block that cannot be read keeps its own source on the page under a single
plot: … line saying what is wrong — an unknown function, a range that does
not increase, a bracket that was never closed. Never a hole, never an error
box.
Mermaid
A fenced ```mermaid block draws a Mermaid diagram — flowcharts,
sequence and class diagrams, state machines, Gantt charts and the rest of
what Mermaid 11 can draw — and follows the light or dark theme of the page
it sits on.
Graphviz
A fenced ```dot, ```graphviz or ```gv block is laid out by
Graphviz. Every layout program can be named as the block's language
instead — neato, circo, fdp, sfdp, twopi, osage and
patchwork — so the same graph becomes a hierarchy, a spring model, a
circle or a radial fan by changing one word.
PlantUML
A fenced ```plantuml or ```puml block draws the UML family and the
good deal more PlantUML can draw beside it: sequence, class, component,
activity, state, mind maps, work breakdowns and Gantt charts.
One boundary is worth knowing before you meet it. PlantUML lays some
diagrams out itself and hands the rest to Graphviz, and Graphviz is
WebAssembly, which VS Code's built-in Markdown preview forbids. So in the
preview you get sequence diagrams, the modern activity syntax
(start / if / stop), mind maps, Gantt charts, WBS, JSON, YAML, salt
wireframes and timing diagrams; class, state, component, object,
use-case, deployment and ER diagrams — and the legacy (*) --> activity
syntax — show their source instead, after a pause. They are not lost:
md: Preview Diagram draws them in md's own panel, and every export —
HTML, PDF, EPUB, SVG — draws them too, because those render in a webview
this extension owns and can allow WebAssembly in.
Zooming a diagram
A diagram is drawn to fit the page, which leaves a large one too small to
read. Hover a Mermaid, PlantUML or Graphviz diagram in the preview and a
small − Fit + control appears over it: it zooms that one figure, which
then scrolls sideways inside its own block, and Fit puts it back. In
the diagram panel the same three are buttons in the panel's title bar, and
Ctrl / ⌘ with +, − and 0 work while the panel is active.
In both, Ctrl / ⌘ with the scroll wheel, or a trackpad pinch, zooms
the diagram under the pointer. The panel keeps its zoom as you edit.
CSV and TSV blocks
A fenced ```csv or ```tsv block is drawn as a table, quoted fields
and all, with all-number columns lined up on the right. The source stays
the data you pasted, so next month's numbers replace it wholesale instead
of being re-typed into pipes and dashes.
Front matter
YAML or TOML front matter at the very top of a file — --- … --- or
+++ … +++ — is recognised as metadata and hidden from the page and
from every export, instead of surfacing as a horizontal rule followed by
stray text.
An EPUB reads it as the book's metadata: title, author, language
(a tag such as en or pt-BR), date (2026-10-10), description,
and series with series_index reach the reader's library, and cover
names the cover image — a file beside the document, an https: image or
a data: image, in PNG, JPEG, GIF or WebP. A cover that cannot be read
is left out and the book is written without one.
Write [^id] in the text and [^id]: the note on a line of its own. The
notes gather under a rule at the foot of the page, numbered in the order a
reader meets them, each reference linking down to its note and each cited
note linking back.
Task lists, tables and the everyday rest
Headings, bold, italic, inline code, links, strikethrough, block quotes
including nested ones, bullet and numbered lists with nesting, task lists
(- [ ] and - [x]), GitHub-style tables with column alignment, fenced
code blocks that scroll sideways rather than wrap, thematic breaks and
\newpage page breaks for the exports. Author notes — an HTML comment
whose text begins with note:, written on a line of its own — stay in the
file and never reach the page.
Syntax highlighting
A fenced block that names its language reads with its keywords, comments
and strings set apart, in md's own quiet three-tone palette rather than a
bright editor one that would fight the page. Forty-odd languages are
covered. A fence with no language, or one whose language is unknown, stays
plain rather than being guessed at.
Diagram files preview as diagrams
A .puml, .plantuml, .iuml or .pu file, and a .gv or .dot one,
opens as its own language with syntax highlighting and a Preview
Diagram button in the editor title bar. The panel beside it shows the
diagram the file describes and follows every edit, while the source stays
fully editable. A Mermaid file — .mmd or .mermaid — gets the same
button and panel, and Export Diagram as SVG; it is known by its
extension, never guessed from its text.
Markdown files stay VS Code's own. The built-in markdown language opens
.md, .markdown, .mdown, .markdn, .mdtext, .mdtxt, .mkd and
.mdwn; md adds .mkdn and .mkdown to that same language rather than to
one of its own, so every spelling the iPhone, iPad, Mac, Windows, Linux and
Android apps open opens here too — in the preview you already use, with the
same commands, and with nothing about how a .md file behaves changed.
Exports
Export as HTML… writes one self-contained file that opens anywhere with
nothing beside it — diagrams as drawings, formulas as selectable text.
Export as PDF… prints that same page at A4, A5, US Letter or Legal, or
at a print-on-demand trim size (6 × 9″, 5 × 8″, 5.5 × 8.5″).
Export as EPUB… builds an e-book whose table of contents is the
document's own headings, with an identifier derived from the title, so
re-exporting updates the reader's copy instead of stacking up beside it —
and a chart travels into that book as vector, while a diagram arrives as a
picture. Export as LaTeX… writes .tex in which your mathematics is still
the $…$ you typed rather than a picture of it; a diagram or a chart
travels as the source you wrote, under a comment naming its language.
Export as TextBundle… and Export as TextPack… write the format Bear,
Ulysses and every md app share: the text with an assets/ folder holding
each image the document refers to by a relative path, so it arrives with
its pictures. Export Diagram as SVG… saves one diagram, or one chart, as
a real vector file.
All of them are on the right-click menu as well as in the Command
Palette: md: Export opens as a submenu on a Markdown file in the
Explorer, in the editor and on the editor tab, with the two diagram
commands beside it on a .puml or .gv file. The menu hands the
command the file you clicked, so the export is of that file rather than
of whatever editor happened to be focused — and of the unsaved text when
the file is open.
A folder of Markdown at once
Select several Markdown files in the Explorer and HTML, EPUB,
LaTeX or TextPack exports all of them: one question — which folder — then a
cancellable progress notification counting through the files, and one
line at the end saying how many landed, naming any that failed and any
non-Markdown file that was skipped. Each export takes its own source
file's name, so notes.md becomes notes.html, and a name already
taken in the destination takes a -2 rather than overwriting what is
there.
PDF is the one export that stays single-file. It writes no bytes
itself — it hands a print-ready page to the host's print dialogue, where
you choose Save as PDF and a destination — so it is not offered for a
multi-selection, and exports one document at a time from the same menu.
Where md's Markdown differs from GitHub's, said out loud
The renderer is a deliberate subset — see Known limitations — which
means a document written for GitHub can render differently here with
nothing to warn you. Now it warns you: a faint underline and a row in the
Problems pane, at Information level and never higher, because the
Markdown is not wrong, it will simply look different.
Five rules, each naming what md does instead: tags written as markup
(escaped, so they show as the characters you typed), reference-style
links and their definition lines (printed as written, both halves), a
four-space indented block (a paragraph here, not code), a table written
straight under a paragraph without the blank line md needs, and a
footnote nothing cites — printed at the foot here, printed nowhere at
all by a CommonMark engine.
Two of them come with a quick fix, and only two: fencing an indented
block and inserting the blank line above a table are rearrangements with
no judgement in them. Which address a reference link meant is a question
only you can answer, so nothing guesses at it.
It reads the document in your editor and nothing else, using the same
parser the preview renders with — so a less-than sign in a sentence is
not a tag, an example shown inside backticks is not a tag, an indented
paragraph under a list item is not a code block, a footnote defined at
the foot of the file is cited, and [^a-z] in a sentence about regular
expressions is a character class rather than a citation. Switch it off entirely with
md.lint.dialect, or one rule at a time with md.lint.rules.
Commands
All of them appear in the Command Palette under the md category, and in
the context menus below.
| Command |
What it does |
Offered when |
| md: Export as HTML… |
One self-contained .html file, engines and fonts included |
a Markdown, PlantUML or Graphviz editor is active, or such files are selected — in batch too |
| md: Export as PDF… |
The rendered document as a PDF, at the size in md.export.pageSize |
a Markdown, PlantUML or Graphviz editor is active, or one such file is selected |
| md: Export as EPUB… |
An e-book with the document's headings as its contents |
a Markdown, PlantUML or Graphviz editor is active, or such files are selected — in batch too |
| md: Export as LaTeX… |
.tex source, mathematics kept as mathematics |
a Markdown editor is active, or Markdown files are selected — in batch too |
| md: Export as TextBundle… |
A .textbundle folder: text.md, info.json and the document's local images in assets/ |
a Markdown editor is active, or one Markdown file is selected |
| md: Export as TextPack… |
The same bundle zipped into one .textpack file |
a Markdown editor is active, or Markdown files are selected — in batch too |
| md: Export Diagram as SVG… |
One Mermaid, Graphviz or PlantUML diagram, or one chart, as a vector file |
a Markdown, PlantUML, Graphviz or Mermaid editor is active, or one diagram file is selected |
| md: Preview Diagram |
Opens the diagram panel beside a diagram file |
a PlantUML, Graphviz or Mermaid editor is active, or one diagram file is selected |
| md: Go to Heading… / Go to Note… |
Jump to a heading, or to one of the document's private notes, from a list that follows as you move through it |
a Markdown editor is active |
| md: Zoom In / Zoom Out / Reset Zoom |
Zoom the diagram in the diagram panel; Reset fits it to the panel again (Ctrl / ⌘ +, −, 0) |
the diagram panel is the active editor |
Mathematics is not on the SVG list, because KaTeX sets a formula as HTML
and text and there is no vector drawing to hand over.
Settings
Every setting is resource-scoped, so it can be set for the user, for a
workspace or for one folder.
| Setting |
Default |
What it does |
md.preview.theme |
editor |
Which colours and fonts the preview draws in: editor follows your VS Code theme, paper is md's own typewriter look |
md.preview.bodyFont |
(empty) |
Font stack for preview prose. Empty means follow the chosen theme |
md.preview.codeFont |
(empty) |
Font stack for code blocks and inline code. Empty means follow the chosen theme |
md.math.enabled |
true |
Typeset $…$, $$…$$ and ```math with KaTeX, chemistry included |
md.diagrams.mermaid |
true |
Render ```mermaid blocks |
md.diagrams.graphviz |
true |
Render ```dot, ```graphviz, ```gv and the layout-named fences |
md.diagrams.plantuml |
true |
Render ```plantuml and ```puml blocks |
md.diagrams.plot |
true |
Draw ```plot blocks as charts |
md.highlight.enabled |
true |
Syntax-highlight fenced code blocks that name a language |
md.export.pageSize |
A4 |
Page size for PDF export: A4, A5, Letter, Legal, 6x9, 5x8, 5.5x8.5 |
md.statusBar.wordCount |
true |
The document's words and characters in the status bar while a Markdown editor is active, counted as the md apps count them; the selection's too when there is one |
md.lint.dialect |
true |
Point out, at Information level, where md's Markdown differs from GitHub's |
md.lint.rules |
(all on) |
Which of the five differences are reported: rawHtml, referenceLink, indentedCode, tableAfterParagraph, footnote |
Turning an engine off leaves the block readable as the source you wrote.
It is never blank and never an error box — and the engine itself is never
fetched, so a document full of PlantUML with md.diagrams.plantuml off
costs the preview nothing rather than 7.4 MB. Charts are the odd one out
among those switches: there is no engine behind them, so turning
md.diagrams.plot off loads nothing less — it is there for when the numbers
behind a figure are what you would rather read.
Themeing
By default the preview looks like the rest of your editor. It takes the
colours of your current colour theme and the typography of the built-in
Markdown preview — your markdown.preview.fontFamily,
markdown.preview.fontSize and markdown.preview.lineHeight — with your
editor.fontFamily for code. Change your theme and the page changes with
it, diagrams included.
Set md.preview.theme to paper and the page becomes md's own instead:
warm "fresh paper" in a light theme, "carbon paper" in a dark one, set in
American Typewriter with Courier New for code, matching the iPhone, iPad,
Mac and Android apps. md.preview.bodyFont and md.preview.codeFont
override either theme's faces where a machine lacks them.
Privacy
Everything renders on your machine, from engine files that live inside the
extension. md has no account, no telemetry and no servers of ours to send
anything to. It reads the document you are previewing and writes only the
file you name when you ask for an export. The single thing that can reach
the network is an image your own document names by URL, which the
preview fetches so it can show it, exactly as a browser would — or that
an EPUB's front matter names as its cover:. Visual
Studio Code's own telemetry is the editor's, governed by your
telemetry.telemetryLevel and by Microsoft's privacy statement. This
extension adds nothing to it and reads nothing from it. The full policy is
in PRIVACY.md.
Requirements
- Visual Studio Code 1.95 or later.
- Desktop VS Code. The mathematics, highlighting and Graphviz engines run
in the extension host and read their files from disk, which the browser
extension host cannot do, so there is no
vscode.dev build rather than
one that silently renders half a document.
- Any workspace: trusted, Restricted Mode, or virtual (GitHub
Repositories and the like). In Restricted Mode the two font settings
come from your user settings only.
Known limitations
Said plainly, because each one is a decision rather than an oversight.
- A deliberate subset, not a CommonMark engine. The renderer is the
apps' renderer and inherits their omissions on purpose: raw HTML is
escaped rather than passed through, so tags render as the characters you
typed, there are no reference-style links, and a four-space indent
continues a paragraph rather than starting a code block. None of that
is going to change — but the extension no longer leaves you to find it
out from the preview:
md.lint.dialect reports each of them where it
is written, at Information level.
- PDF output is not byte-identical to the apps'. Same page sizes, same
margins, same content, a different rasterizer — and American Typewriter
does not exist away from Apple, so the glyphs themselves differ.
- An exported EPUB keeps its code plain. The e-book is built from the
document before any colouring is applied, on every platform md ships on.
- An author note is hidden only on a line of its own. Written inline,
it renders.
- View modes belong to VS Code, not to md. The iPhone, iPad, Mac,
Windows, Linux and Android apps remember whether each file was last
open in the editor, the preview or a split, because they own their
whole window. Here the editor owns it: Open Preview and Open Preview to
the Side place the preview, View: Toggle Editor Group Layout
rearranges the columns, and VS Code restores your groups and tabs
itself. md keeps no memory of its own, adds no setting for one and
opens no preview uninvited.
What changed
Every release is listed in the Changelog tab of this page, and in
CHANGELOG.md on GitHub.
The rest of the family
md is also a native app on five other platforms, sharing this renderer —
the same mathematics, diagrams and charts — and these export formats.
md for Windows
A Markdown editor and live previewer for Windows 11, on x64 and ARM64,
from the Microsoft Store.
Write on one side and watch the finished page take shape on the other, in
Edit, Split and Preview layouts, with a Zen mode that gives your text the
whole screen. The page is this extension's page — LaTeX and chemistry,
Mermaid, Graphviz and PlantUML, plots — drawn offline on your PC. Print it,
export it as PDF, HTML, EPUB, LaTeX or a TextBundle, or compile a folder of
chapters into one book. It opens every spelling of Markdown this extension
does, saves in place as you write, and has no accounts, no analytics and
no tracking. The source is at
github.com/nettrash/md.win.
md for Linux
A Markdown editor and live previewer for Linux — a native GTK 4 and
libadwaita app, the Linux edition of md for Mac — on x86-64 and ARM64: a
.deb for Ubuntu 26.04 LTS, an .rpm for Fedora 44 and later, and a
portable .tar.gz for other distributions, all from
nettrash.me. Write
on one side and watch the finished page take shape on the other, in Edit,
Split and Preview layouts, with a Zen mode that gives your text the whole
screen. The page is this extension's page — LaTeX and chemistry, Mermaid,
Graphviz and PlantUML, plots — drawn offline on your computer. Print it,
export it as PDF, HTML, EPUB, LaTeX or a TextBundle, or compile a folder of
chapters into one book. It opens every spelling of Markdown this extension
does, saves in place as you write, and has no accounts, no analytics and
no tracking. Installing and support are at
nettrash.me/linux/md.
iPhone, iPad, Mac and Android
Questions and bug reports are welcome at
github.com/nettrash/md.vscode/issues.
Licence
MIT — see LICENSE. © 2026 nettrash.
The mathematics, diagram and highlighting engines are open-source projects
carried inside the extension, under their own licences:
| Engine |
Version |
Licence |
| KaTeX, with the mhchem extension |
0.17.0 |
MIT |
| Mermaid |
11.16.0 |
MIT |
| Viz.js, carrying Graphviz |
3.24.0 / 14.1.1 |
Viz.js MIT, Graphviz EPL-1.0, Expat MIT |
| PlantUML |
1.2026.4beta4 |
GPL |
| highlight.js, the common-languages build |
11.11.1 |
BSD-3-Clause |
Mermaid's own bundle carries DOMPurify under the Apache License 2.0 and
the Mozilla Public License 2.0, and js-yaml, Lodash and parts of Cytoscape
under MIT.