Migrate Evernote Notes to AI Memory

You have years of notes in Evernote -- meeting notes, clipped articles, research, and ideas. This guide shows how to export your Evernote notebooks, parse the ENEX format, and import everything into REM Labs so your AI can recall any note with semantic search.

Step 1: Export from Evernote

  1. Open Evernote Desktop
  2. Select a notebook (or All Notes)
  3. Edit > Select All (Ctrl+A / Cmd+A)
  4. File > Export Notes > ENEX format
  5. Save as evernote-export.enex

ENEX is an XML format containing note content as HTML, plus metadata like tags, creation date, and notebook name.

Step 2: Parse ENEX Files

npm install @remlabs/sdk fast-xml-parser html-to-text
import { XMLParser } from "fast-xml-parser"; import { convert } from "html-to-text"; import fs from "fs"; function parseEnex(filePath) { const xml = fs.readFileSync(filePath, "utf-8"); const parser = new XMLParser({ ignoreAttributes: false, attributeNamePrefix: "@_" }); const parsed = parser.parse(xml); const notes = Array.isArray(parsed["en-export"].note) ? parsed["en-export"].note : [parsed["en-export"].note]; return notes.map(note => { const htmlContent = note.content || ""; const plainText = convert(htmlContent, { wordwrap: false, selectors: [ { selector: "img", format: "skip" }, { selector: "en-media", format: "skip" } ] }); const tags = note.tag ? (Array.isArray(note.tag) ? note.tag : [note.tag]) : []; return { title: note.title || "Untitled", content: plainText, tags, created: note.created, updated: note.updated }; }); } const notes = parseEnex("evernote-export.enex"); console.log(`Parsed ${notes.length} notes`);

Step 3: Import into REM Labs

import { RemClient } from "@remlabs/sdk"; const rem = new RemClient({ apiKey: process.env.REMLABS_API_KEY }); let imported = 0; for (const note of notes) { if (!note.content || note.content.trim().length < 20) continue; await rem.remember({ content: `${note.title}\n\n${note.content}`, namespace: "evernote", tags: note.tags, metadata: { title: note.title, source: "evernote", created: note.created, updated: note.updated, original_tags: note.tags } }); imported++; if (imported % 50 === 0) { console.log(`Imported ${imported}/${notes.length}`); } } console.log(`Migration complete: ${imported} notes imported`);

Step 4: Query Your Archive

// Search years of notes with natural language const results = await rem.recall({ query: "meeting notes about the product roadmap", namespace: "evernote", limit: 10 }); results.forEach(m => { console.log(`${m.metadata.title} (${m.metadata.created})`); console.log(` Tags: ${m.metadata.original_tags.join(", ")}`); console.log(` ${m.content.slice(0, 120)}...\n`); }); // Filter by Evernote tags const workNotes = await rem.recall({ query: "client feedback on the new design", namespace: "evernote", tags: ["work", "design"], limit: 5 });

Handling Large Exports

For users with thousands of notes, process in batches with rate limiting:

import pLimit from "p-limit"; const limit = pLimit(5); const tasks = notes .filter(n => n.content && n.content.trim().length >= 20) .map(note => limit(() => rem.remember({ content: `${note.title}\n\n${note.content}`, namespace: "evernote", tags: note.tags, metadata: { title: note.title, source: "evernote" } }) )); await Promise.all(tasks); console.log(`Imported ${tasks.length} notes`);

Web clips and images: ENEX files may contain web clippings with heavy HTML and embedded images. The html-to-text parser strips these to clean text. If you need image content, consider using an OCR service before importing.

Unlock your Evernote archive with AI

Free tier. ENEX parsing included. Semantic search on years of notes.

Get Started