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
Technical Specifications & ENML Migration Rules
- GFM Task List Synthesis: Maps `<en-todo checked="true"/>` directly to `- [x]` and unchecked tags to `- [ ]`; adjacent checkbox blocks are rejoined into tight GFM task lists so they render as a single checklist in Obsidian and on GitHub rather than as loose paragraphs.
- YAML Frontmatter & Metadata Extraction: Single-note exports extract `<title>`, `<created>`, `<updated>`, and `<tag>` arrays into Obsidian-compatible YAML frontmatter; ISO basic timestamps (`20240105T102200Z`) normalize to extended ISO 8601 (`2024-01-05T10:22:00Z`) so Dataview and static-site generators parse them as real dates.
- Multi-Note Thematic Separation: Multi-note notebook exports emit an H1 per note with inline hashtags and metadata, separated by thematic breaks (`---`) to allow clean scripted splitting into one file per note.
- Attachment Placeholders & Encryption: `<en-media/>` tags referencing sibling binary resources by MD5 hash emit descriptive placeholders; encrypted `<en-crypt>` blocks are safely flagged as unconverted rather than emitting base64 noise.
- Sanitisation of Proprietary Tags: DOMPurify allow-lists inert ENML elements before conversion while stripping inline styles, `<font>` tags, and legacy color attributes, preserving structural markup such as headings, lists, tables, links, and code.
Developer Alternative: CLI (yarle) & Python (html2text) Migration
For batch pipelines or server-side automation, yarle and html2text produce the same kind of Markdown outside the browser.
# Batch convert Evernote ENEX notebooks to Obsidian Markdown using yarle CLI
npx -p yarle-evernote-to-md yarle --enexSource=notebook.enex --outputDir=./notes# Programmatic ENEX parsing and Markdown extraction using Python
# requires: pip install html2text
import xml.etree.ElementTree as ET
import html2text
tree = ET.parse("notes.enex")
converter = html2text.HTML2Text()
converter.body_width = 0
for note in tree.findall(".//note"):
title = note.find("title").text if note.find("title") is not None else "Untitled"
content = note.find("content").text or ""
markdown = converter.handle(content)
print(f"# {title}\n\n{markdown}\n---")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.
Parses on the main thread
Parsing stays inside your browser tab — this format’s parser needs DOM APIs. Nothing is uploaded. 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.
- fast-xml-parser (ENEX outer XML structure parser)ENEX parsing
- Turndown (ENML to GFM Markdown)ENML conversion
- DOMPurify (Client-side ENML sanitisation)ENML sanitisation
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, attachments and encrypted blocks?
Images and files 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 — each reference becomes a visible placeholder naming the media type, and a warning reports how many attachments the export contained. Encrypted <en-crypt> blocks are flagged as unconverted rather than emitted as base64 noise, so you know which notes need attention in Evernote.
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. Single-note exports instead emit clean YAML frontmatter at the top of the file.