Convert Evernote Notes (.enex) to Markdown
.enex export to Markdown with the parts a vault actually organises around: fast-xml-parser reads the note list and lifts each note’s tags and timestamps, the ENML body is sanitised and run through Turndown, and <en-todo/> checkboxes become real GFM task lists. It runs in a Web Worker in your browser — your notes are never uploaded.Processing happens 100% in your browser — nothing is uploaded.
How to convert Evernote ENEX to Markdown
- Export from Evernote: select your notes or notebook, choose Export, and save as .enex — then drop that file onto the dropzone.
- Local processing: fast-xml-parser reads the note list, metadata is lifted, and each ENML body is sanitised and converted to Markdown in a Web Worker.
- Copy or download: copy the Markdown or save it as a .md file. Multi-note exports are separated by a thematic break, which is the seam to split on for one file per note.
Why Convert Evernote to Markdown with MD Convert?
Checkboxes become GFM task lists, not lost markup
A dedicated Turndown rule maps <en-todo checked="true"/> to - [x] and an unchecked or absent attribute to - [ ]. Because each checklist row is its own block element, adjacent task lines are then rejoined into a tight list rather than left as loose paragraph-wrapped items.
Tags, created and updated dates preserved
Every <tag>, both timestamps and the clipped source-url are lifted from the note. A single-note export receives them as YAML frontmatter — what Obsidian reads as properties — while a multi-note export gets an H1 per note with the same metadata inline beneath it, tags rendered as #hashtags.
ENML parsed correctly, CDATA and all
Note bodies are ENML wrapped in a CDATA section, which parses to an object rather than a string. Lifting the CDATA payload explicitly is what produces a real note body instead of the literal text [object Object], and the proprietary en- elements are allow-listed through the sanitiser so their state survives to the conversion rules.
A migration with no third party involved
An Evernote archive is often the most personal file a person owns. Reading the file, parsing the XML, sanitising the ENML and running Turndown all happen in a Web Worker on your device — no upload, no account, no server-side record of what you converted.
Evernote to Markdown: Before and After
`<en-todo checked="true"/>` sits at the start of the line it belongs to, so it maps directly onto a GFM task marker. A single-note export puts its title, timestamps and tags into YAML frontmatter, which is exactly what Obsidian reads as note properties.
<note>
<title>Release checklist</title>
<created>20240105T102200Z</created>
<tag>release</tag>
<content><![CDATA[<en-note>
<div><en-todo checked="true"/>Tag the release</div>
<div><en-todo/>Publish the notes</div>
</en-note>]]></content>
</note>---
title: "Release checklist"
created: 2024-01-05T10:22:00Z
tags: ["release"]
---
- [x] Tag the release
- [ ] Publish the notesUnderstanding the Evernote Format: Evernote ENML DTD
- Format
- Evernote Export Format (ENEX) / ENML
- Specification
- Evernote ENML DTD
- Media type
application/enex+xml- Parser used
- fast-xml-parser + Turndown
An `.enex` file is a single XML document with an `<en-export>` root holding one `<note>` element per exported note. Each note carries its `<title>`, `<created>` and `<updated>` timestamps, zero or more `<tag>` elements, a `<note-attributes>` block (source URL, author, geolocation) and a `<content>` element that contains the note body.
That body is not HTML and not plain XML — it is ENML, Evernote's own dialect, wrapped in a CDATA section so its angle brackets survive inside the XML. ENML is HTML with the interactive parts removed and three proprietary elements added: `<en-todo/>` for a checkbox, `<en-media/>` for an embedded attachment, and `<en-crypt>` for passphrase-encrypted text.
Conversion therefore happens in two stages. fast-xml-parser reads the outer XML and gives back the note list with its metadata, the CDATA body is lifted out of `<content>`, and Turndown converts that ENML to Markdown with dedicated rules for the three proprietary elements. Getting the CDATA extraction right is what separates a real note body from the literal text `[object Object]` — a CDATA node parses to an object, not a string.
Checklists become real GFM task lists
`<en-todo/>` is a void element that sits immediately before the text of the item it marks, inside that item's own block element. A dedicated Turndown rule emits `- [x] ` when its `checked` attribute is the string `"true"` and `- [ ] ` otherwise — Evernote omits the attribute entirely for an unchecked box, so absence is correctly read as unchecked rather than as unknown.
There is a second step that matters for how the result renders. Because each checklist row is its own block-level element, Turndown separates consecutive items with a blank line, which in GFM is a *loose* list — every item gets wrapped in a paragraph and displays with extra leading. Adjacent task lines are rejoined afterwards so you get the tight list a hand-written checklist would have, while genuine paragraph breaks elsewhere in the note are left alone.
This is also where a sanitiser detail becomes visible. Note bodies are untrusted HTML, so they pass through DOMPurify before Turndown — and DOMPurify's HTML profile drops anything outside the HTML namespace, which includes every `en-` element. The ENML elements are explicitly allow-listed (they are inert and carry no script surface) so the checkbox state survives sanitisation instead of being stripped before the rules can read it.
Tags, timestamps and source URLs are preserved
Metadata is the reason an Evernote migration succeeds or has to be redone by hand, so all of it is lifted: the title, the `<created>` and `<updated>` timestamps, every `<tag>` element, and the `source-url` from `<note-attributes>` for notes clipped from the web.
Where that metadata lands depends on how many notes the export holds. A single-note export becomes one Markdown document, so the metadata is emitted as YAML frontmatter — the format Obsidian reads as note properties and Hugo and Jekyll read as front matter. Titles are written as double-quoted YAML scalars, so a title containing a colon or a quotation mark cannot break the block.
A multi-note export becomes one document containing every note, and a second frontmatter block partway down a file is not frontmatter — it is just text between two horizontal rules. Each note therefore gets an H1 title with an inline metadata line beneath it, with tags rendered as `#hashtags` so they stay clickable the moment the text lands in a vault. Notes are separated by a thematic break, so splitting the output into one file per note is a mechanical operation.
ENEX timestamps use the ISO 8601 *basic* format (`20240105T102200Z`), which YAML does not recognise as a date. They are normalised to the extended form (`2024-01-05T10:22:00Z`) so Obsidian, Hugo and Jekyll all parse the value as a real timestamp rather than as an opaque string.
Attachments, encrypted blocks and inline styling
`<en-media/>` does not contain the attachment. It references one by the MD5 hash of its bytes, and the bytes themselves live in a sibling `<resource>` element as base64. Resolving the reference would mean hashing every resource in the file to find the match, so each reference becomes a visible placeholder naming the media type instead — and a warning reports how many attachments the export contained. Silently dropping them would lose the fact that anything was attached at all.
`<en-crypt>` blocks hold text encrypted with a passphrase that is not stored in the export. They are marked as encrypted-and-not-converted rather than emitted as base64 noise, so you can see which notes need attention in Evernote before the export is discarded.
Inline presentational markup is removed rather than translated. Evernote notes accumulate `style` attributes from years of pasting — fonts, colours, background highlights — and the sanitiser strips both `style` attributes and `<style>` elements before conversion. What survives is the structural markup: headings, lists, tables, links, code, emphasis and strong.
A migration that happens entirely in your browser
An Evernote archive is usually the most personal file a user owns: years of medical notes, client records, passwords pasted into a note once and forgotten. Every step here — reading the file, parsing the XML, sanitising the ENML, running Turndown — happens in a Web Worker in your own browser. The file is never uploaded, there is no account, and there is no server-side log of what you converted.
You can confirm it rather than trust it. Open DevTools, watch the Network panel, and convert: no request carries your data. The only traffic is the initial page load and the on-demand parser chunks.
For a large archive, exporting from Evernote in batches is worth doing anyway — not because of a size limit here, but because one `.md` file per note is what a vault wants, and smaller exports make that split trivial. The thematic break between notes is the seam to cut on.
Known limitations of Evernote to Markdown conversion
Being explicit about what a converter cannot do saves you a wasted upload. These are the boundaries of what is recoverable from Evernote programmatically:
- Attachments are not embedded. `<en-media/>` references a binary by hash, and the reference becomes a placeholder naming the media type.
- Encrypted `<en-crypt>` blocks cannot be decrypted without the note passphrase and are marked as unconverted.
- A multi-note export produces one Markdown document with notes separated by a thematic break, not one file per note.
- Only single-note exports get YAML frontmatter; multi-note exports carry the same metadata as an inline line under each note's H1, because frontmatter is only valid at the top of a file.
- Inline styling (fonts, colours, highlights) is intentionally stripped. Markdown has no equivalent, and keeping it would mean emitting raw HTML.
- Evernote-internal note links (`evernote:///` URLs) are preserved as written and will not resolve once the notes live in another tool.
- Nested checklists inside table cells are flattened, since a Markdown table cell cannot contain a list.
Who Converts Evernote to Markdown?
Obsidian migrants
Moving years of notes into a vault as plain Markdown with tags and creation dates intact, so Dataview queries and graph links still work.
Logseq & Notion users
Importing an Evernote archive as CommonMark, keeping checklists as real task items rather than as flattened text.
Developers & Researchers
Getting code snippets and clipped documentation out of a proprietary container and into a Git-tracked, grep-able notes repository.
Privacy-conscious professionals
Migrating notes that contain client details or credentials without uploading the export to a third-party conversion service.
How You Can Verify the Privacy Claim
Zero server upload
Conversion runs inside your browser tab. Open DevTools, switch to the Network panel, and convert a file: for every format except URL to Markdown you will see no request carrying your document — because there is no endpoint to send it to.
Off the main thread
Heavy parsing is dispatched to a Web Worker, so a 500-page PDF or a large spreadsheet never freezes the interface. Everything is plain JavaScript — no native plugin, no WebAssembly toolchain, nothing to install.
Nothing to sign up for
No login, no quota, no paywall, and no tracking tied to your files. Analytics are cookieless and aggregate only. Read the privacy policy for the full data-flow breakdown, including the one proxied exception.
The parsers doing the work
No proprietary black box: each format is handled by a widely audited open-source library, running client-side at the version pinned in our lockfile.
Evernote to Markdown — FAQ
Are my Evernote checklists converted to Markdown task lists?
Yes. <en-todo checked="true"/> becomes - [x] and an unchecked box becomes - [ ]; Evernote omits the attribute entirely when a box is unchecked, so its absence is correctly read as unchecked. Consecutive items are emitted as a tight list, so they render as a single checklist in Obsidian and on GitHub rather than as separate paragraphs.
Does it keep my tags and creation dates for Obsidian?
Yes. Tags, created, updated and the source URL are all lifted. A single-note export puts them in YAML frontmatter, which is exactly what Obsidian reads as note properties and what Hugo and Jekyll read as front matter. ENEX timestamps use the ISO 8601 basic format, so they are normalised to the extended form (2024-01-05T10:22:00Z) that those tools parse as real dates.
What happens to images and attachments in my notes?
They are not embedded. An <en-media/> element references a binary by the MD5 hash of its bytes, and the bytes live in a separate <resource> element as base64 — resolving that would mean hashing every resource to find the match. Each reference becomes a visible placeholder naming the media type, and a warning reports how many attachments the export contained, so you know what to re-attach.
Why is my whole notebook one Markdown file?
Because one .enex export is one XML document containing every note. Notes are separated by a thematic break with an H1 title each, so splitting the output into one file per note is mechanical. Exporting from Evernote in smaller batches — a notebook at a time — makes that split easier if you are building a vault.
Is my note data uploaded to a server?
No. Everything runs in a Web Worker in your own browser: the file read, the XML parse, the DOMPurify pass and Turndown. Nothing is transmitted and there is no account, which matters for an archive that may hold medical notes, client records or passwords. Watch the Network panel in DevTools while converting to confirm it.