Integration
Migration
April 13, 2026
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
- Open Evernote Desktop
- Select a notebook (or All Notes)
- Edit > Select All (Ctrl+A / Cmd+A)
- File > Export Notes > ENEX format
- 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