Convert Evernote ENEX exports to Markdown with full attachment support
A fast Go tool to convert Evernote .enex export files to Markdown format. Designed for seamless import into mddb (Markdown Database) and other markdown-based tools.
- Full ENEX Support - Parses Evernote export files with complete metadata
- Attachment Extraction - Extracts images, PDFs, and other files to
resources/folder - Code Block Detection - Properly formats Evernote code blocks with fenced markdown
- Tag Preservation - All tags included in YAML frontmatter
- Rich Content Conversion - Headers, lists, tables, code blocks, checkboxes
- SEO-friendly Filenames - Clean, URL-safe filenames from note titles
- UTF-8 Throughout - Proper encoding for international content
- mddb Ready - Output format compatible with mddb (Markdown Database)
# Homebrew (macOS/Linux)
brew install spagu/tap/enex2md
# Using go install
go install github.com/spagu/enex2md/cmd/enex2md@latest
# Ubuntu/Debian
wget https://github.com/spagu/enex2md/releases/latest/download/enex2md_1.0.0_amd64.deb
sudo dpkg -i enex2md_*.deb
# RedHat/CentOS/Fedora
wget https://github.com/spagu/enex2md/releases/latest/download/enex2md-1.0.0.x86_64.rpm
sudo rpm -i enex2md-*.rpm
# Snap
sudo snap install enex2md
# From source
git clone https://github.com/spagu/enex2md.git
cd enex2md
make build# Convert ENEX file
enex2md -i notes.enex -o ./markdown
# Short flags
enex2md -i export.enex -o ./notes
# Show version
enex2md --version| Flag | Short | Description | Default |
|---|---|---|---|
--input |
-i |
Path to ENEX file (required) | - |
--output |
-o |
Output directory | . |
--version |
-v |
Show version info | - |
--help |
-h |
Show help | - |
Each note becomes a Markdown file with YAML frontmatter:
---
title: "Meeting Notes"
created: 2025-12-08T15:38:50Z
updated: 2026-01-23T17:55:47Z
author: "John Doe"
tags:
- "work"
- "meetings"
---
# Meeting Notes
Content converted to clean Markdown...
```bash
# Code blocks are properly formatted
echo "Hello World"
### Output Structure
output/ ├── meeting-notes.md ├── project-ideas.md ├── untitled.md └── resources/ ├── screenshot.png ├── document.pdf └── photo.jpg
## Docker Usage
### Build and Run
```bash
# Build Docker image
docker build -t enex2md .
# Convert ENEX file (mount volumes)
docker run --rm \
-v /path/to/your/notes.enex:/data/notes.enex \
-v /path/to/output:/output \
enex2md -i /data/notes.enex -o /output
# docker-compose.yml
services:
enex2md:
build: .
volumes:
- ./data:/data:ro
- ./output:/output
command: ["-i", "/data/notes.enex", "-o", "/output/markdown"]
mddb:
image: ghcr.io/tradik/mddb:latest
ports:
- "11023:11023"
- "11024:11024"
volumes:
- mddb_data:/data
environment:
- MDDB_DATA_DIR=/data
depends_on:
enex2md:
condition: service_completed_successfully
volumes:
mddb_data:Run with:
docker compose upmddb (Markdown Database) is a Go-based embedded database with HTTP/gRPC APIs for indexing and querying Markdown files.
# 1. Export from Evernote (File > Export Notes > ENEX)
# 2. Convert to Markdown
enex2md -i export.enex -o ./notes
# 3. Start mddb server
docker run -d -p 11023:11023 -v ./notes:/data ghcr.io/tradik/mddb:latest
# 4. Access via HTTP API on port 11023 or gRPC on port 11024#!/bin/bash
# convert-and-index.sh
INPUT_FILE="${1:-notes.enex}"
OUTPUT_DIR="${2:-./markdown}"
# Convert ENEX to Markdown
enex2md -i "$INPUT_FILE" -o "$OUTPUT_DIR"
# Start mddb with the converted files
docker run -d --name mddb \
-p 11023:11023 \
-p 11024:11024 \
-v "$OUTPUT_DIR":/data \
ghcr.io/tradik/mddb:latest
echo "Done! mddb running on http://localhost:11023"| Element | Markdown Output |
|---|---|
| Headers (h1-h6) | # ## ### ... |
| Bold/Italic | **bold** *italic* |
| Lists | - item / 1. item |
| Links | [text](url) |
| Images |  |
| Code blocks | ```code``` |
| Blockquotes | > quote |
| Tables | Markdown tables |
| Checkboxes | [ ] / [x] |
| Attachments | Extracted to resources/ |
- Go 1.26+
- Make
make all # Full pipeline: deps, fmt, lint, vet, sec, test, build
make build # Build binary
make test # Run tests with race detection
make test-coverage# Generate coverage report
make lint # Run golangci-lint
make vet # Run go vet
make sec # Run gosec security scanner
make fmt # Format code
make clean # Remove build artifactsenex2md/
├── cmd/enex2md/ # CLI entry point (Cobra)
├── internal/
│ ├── enex/ # ENEX XML parser
│ └── converter/ # Markdown converter
├── Dockerfile
├── docker-compose.yml
├── Makefile
├── go.mod
├── README.md
└── CHANGELOG.md
For security concerns, please see our Security Policy.
We welcome contributions! Please see our Contributing Guidelines for details.
Quick start:
- Fork the repository
- Create feature branch (
git checkout -b feature/amazing) - Run tests (
make all) - Commit changes (
git commit -m 'Add feature') - Push branch (
git push origin feature/amazing) - Open Pull Request
BSD 3-Clause License - see LICENSE for details.
Copyright (c) 2026, Tradik Limited
Made with Go by Tradik Limited

