Markdown is easy to write and awkward to hand to someone who does not use it. This converts it to a formatted document you can save as a PDF, with a live preview so you see the result before you commit. Nothing is uploaded — the conversion runs entirely in your browser, which is why it also works offline.
Markdown to PDF Converter
LiveIn the print dialog, set the destination to “Save as PDF”. Turn off headers and footers under “More settings” if the document is going to someone else — browsers print the page URL and date on every sheet by default.
Why the browser, not a library
Every comparable converter loads a JavaScript PDF library. The smallest usable one adds roughly 250 KB to the page — more than seven times the weight of this entire tool. Your browser already contains a print-to-PDF engine, and it is better at the job in every measurable way:
| Aspect | Browser print engine | JavaScript library |
|---|---|---|
| Page weight | Nothing — already installed | 250–1,100 KB depending on the library |
| Font embedding | Correct, including fallbacks | Requires bundling font tables; often substitutes silently |
| Page breaks | Full CSS paged-media support | Approximated, frequently splits tables and headings |
| File size | Smaller — native compression | Typically 2–4× larger for the same document |
| User steps | Two: click, then choose Save as PDF | One: click download |
The library wins on exactly one axis — a single click instead of two. That is the whole trade, and it is not worth a quarter of a megabyte and a worse file.
What is supported
| Syntax | Renders as |
|---|---|
# Heading through ###### Heading | Six heading levels |
**bold** · *italic* · ~~strikethrough~~ | Inline emphasis |
`code` and fenced blocks | Monospaced, whitespace preserved |
- item · 1. item | Bulleted and numbered lists |
[text](url) | Links, kept clickable in the PDF |
> quote | Blockquote |
| Pipe tables | Bordered table with a header row that repeats across pages |
--- | Horizontal rule |
 | Images, scaled to the page width |
Nested lists, task lists and quotes
These three are where most in-browser converters quietly fail, because each needs the parser to track state across lines rather than transform one line at a time:
| Written as | What it becomes |
|---|---|
- a - b | A sublist inside the first item. Indentation is read before the bullet is stripped — strip it first and the sublist flattens into a sibling |
- [ ] todo- [x] done | Drawn checkboxes, ticked or not. A real <input> prints inconsistently and cannot be styled for paper, so these are boxes with a rule |
> quoted | A blockquote, with its contents parsed again — so a list or a heading inside a quote works |
Title===== | An H1. Setext headings appear in older documents and anything pandoc produced |
How this compares to the alternatives
There are four common ways to get a PDF out of Markdown, and they fail in different places:
| Method | Upload required | Works offline | Setup |
|---|---|---|---|
| This page | No | Yes, once loaded | None |
| Most online converters | Yes — the file goes to a server | No | None |
| Pandoc | No | Yes | Command line, plus a LaTeX install for PDF output |
| VS Code extensions | No | Yes | Editor and extension |
Pandoc produces the best-looking output of the four and is the right answer if you convert documents regularly and do not mind the setup. For an occasional document — a report, an invoice, notes you need to send — the upload question is usually what decides it.
Server-side converters are convenient precisely because the work happens elsewhere, which means your document is transmitted to and briefly stored on someone else’s machine. For a shopping list that is irrelevant. For a contract draft, a set of meeting notes naming people, or an invoice carrying bank details, many people would rather it did not happen at all — and there is no way to verify what a server does with a file after it returns the PDF.
Where page breaks fall
A heading stranded at the bottom of a page with its content on the next one is the most common complaint about browser-generated PDFs. The stylesheet here prevents the worst cases:
| Element | Behaviour |
|---|---|
| Headings | break-after: avoid — never separated from the text that follows |
| Tables | Header row repeats on each page via table-header-group |
| Code blocks | break-inside: avoid — kept whole where they fit on one page |
| List items | Not split mid-item |
| Blockquotes and images | Kept whole |
What you cannot do is force a break at a chosen point. Markdown has no concept of pages, so there is no syntax for it — that is a deliberate limitation of the format rather than a gap in this tool. A document that genuinely needs controlled pagination wants a word processor.
Sources: CommonMark Specification 0.31 (Markdown syntax and edge cases) · CSS Paged Media Module Level 3, W3C (break-before, break-after, break-inside) · CSS Fragmentation Module Level 3 (table-header-group behaviour) · Pandoc User's Guide (comparison figures). The 250 KB library figure is the minified, gzipped size of jsPDF 2.5 including its standard font tables.
Which Markdown, exactly
“Markdown” is several things. Knowing which one a tool speaks explains most of the surprises:
| Flavour | Where from | Adds |
|---|---|---|
| Original, 2004 | John Gruber | The base syntax. No tables at all — they were never part of it |
| CommonMark | A strict specification | Resolves the ambiguities in the original. Still no tables |
| GitHub Flavoured | GitHub | Tables, strikethrough, task lists, autolinks. What most people mean by Markdown today |
| MultiMarkdown | Academic writing | Footnotes, citations, metadata blocks, cross-references |
This converter follows GitHub Flavoured Markdown, which is the common denominator in practice. If a table renders as literal pipe characters somewhere else, that tool is running a stricter flavour — it is not broken, it is following the older specification.
What does not survive the trip to paper
| Element | On paper | What to do |
|---|---|---|
| Links | Styled but unclickable | Fine in a PDF read on screen. For print, spell important URLs out in the text |
| Long code lines | Overflow the page width | Wrap them yourself, or accept the clipping. There is no good automatic answer |
| Remote images | Fail silently offline | An image referenced by URL needs the network at conversion time |
| Task list boxes | Render as characters | They are decorative in print anyway |
| Very wide tables | Squeezed or clipped | Split into two tables, or reduce the columns. Paper is not scrollable |
Common mistakes
Frequently asked questions
Is my document uploaded anywhere?
No. The conversion happens in your browser and nothing is transmitted. You can confirm it by disconnecting from the internet after the page loads — the converter keeps working. That matters for the documents people actually convert: contracts, notes, drafts and internal reports.
Why the print dialog instead of a download button?
Because your browser's print engine produces a better PDF than any JavaScript library and adds nothing to the page weight. Libraries start around 250 KB, embed fonts less reliably and handle page breaks worse. The trade is one extra click for a smaller, cleaner file.
Does it handle tables and code blocks?
Yes. Pipe tables render with a header row that repeats on each page, and fenced code blocks keep their whitespace in a monospaced face. Very wide tables still overflow — Markdown has no column-width syntax, so the only fix is fewer columns or landscape orientation.
Can I force a page break?
Not from Markdown syntax, because Markdown has no concept of pages. The stylesheet prevents the worst automatic breaks — orphaned headings, split table headers, broken list items — but it cannot place one for you. A document needing controlled pagination wants a word processor rather than Markdown.
Can I use my own fonts or colours?
Not from here. The output uses a serif body face with monospaced code, which is the combination that reads best on paper and in a PDF reader. If a document needs specific branding, use “Copy as HTML” and style it wherever you normally work.
Why is HTML in my Markdown showing as plain text?
Deliberately. Most renderers pass HTML through, which means pasted text from an unknown source can inject a script or stylesheet into the page. Escaping keeps the output predictable and the page safe. Use “Copy as HTML” if you need raw markup in the document.
How accurate is the page estimate?
It assumes roughly 450 words to a page at 12 pt with default margins, which holds well for prose. Documents heavy in tables, code blocks or images will run longer, because those occupy space that words do not. Treat it as a guide rather than a count.
Do nested and task lists work?
Yes, to any depth. Indent two spaces or one tab per level. Task items written as - [ ] and - [x] become drawn checkboxes rather than literal brackets — drawn rather than real inputs, because a real checkbox prints differently in every browser.
Is my input stored?
No. Everything runs in your browser with no server request, and works offline once the page has loaded. Nothing is written to disk and nothing persists after you close the tab.
What happens to a pipe character inside a table cell?
Write \| and it renders as a literal pipe rather than splitting the cell in two. This matches the same escape convention the Markdown Table Generator writes automatically, so a table built there and pasted here converts correctly.
Does an underscore inside a word like snake_case turn it italic?
No. Underscore emphasis only activates when it is not flanked by a letter, digit or another underscore, so snake_case_words, variable names and file paths print exactly as written. Wrapping a whole word on its own — _word_ — still renders as italic.
Related tools
See the full list of Document Tools, or try:
- PDF to Markdown — the same conversion in reverse
- Markdown Editor — write and check the source before converting it
- Markdown Table Generator — paste from Excel or Sheets, then convert
- Text to PDF — for plain text with no Markdown formatting
- Add Page Numbers to PDF — number the finished document