Self-hosted service
vzhd1701/evernote-backup avatar
vzhd1701/evernote-backup

evernote-backup: three commands to get your Evernote notes out of the cloud

Backup & export all Evernote notes and notebooks

1,768 stars136 forksPythonMIT

At a glance

What is it?
evernote-backup syncs an Evernote or Yinxiang account into a local SQLite database and exports every note as an ENEX file, with the export step running entirely offline. The hard part of the tool is not the export, it is the login, and the README is unusually precise about the three OAuth methods and their limits.
Who is it for?
evernote-backup suits anyone who wants their Evernote or Yinxiang notes in a local, portable form, because the sync is incremental, the database is yours, and the export runs offline with no API access. It is the wrong tool if you want a live two-way sync, since the design is one-way backup and export, and it is the wrong choice if your Evernote account has no local client session, because the import OAuth method depends on the desktop client staying logged in.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 30 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The three command workflow

The whole tool is three commands, and the README is direct that to export all your Evernote data you will have to run three commands.

console
evernote-backup init-db
evernote-backup sync
evernote-backup export output_dir/

The first initialises the local database and authenticates. The second pulls down the notes. The third writes the files.

The features list frames the same thing in three bullets. Quickly sync all your notes into the SQLite database for backup. Export all backed up notes in *.enex format, as notebooks or single notes. And support for both Evernote and Yinxiang.

The separation of sync from export is the design decision that makes this tool trustworthy, and the README explains why. Exporting is performed wholly offline, and does not require access to the Evernote Cloud API to convert the notes.

So the export step cannot fail because the vendor's API changed, and you can re-export at any time without hitting the network. The database is the source of truth for the export, and the sync is the only part that talks to Evernote.

There is a trade in the other direction. Because the export is a full re-export rather than an incremental one, the README notes that evernote-backup export will always re-export all notebooks to the specified output directory, whereas the sync can be scheduled to keep the local database up to date. The schedule applies to the sync, not the export.

The export defaults to packing notes into notebooks, one *.enex file each, and the --single-notes flag extracts each note as its own file, while --include-trash adds trashed notes to the export.

Three OAuth methods, and the session limit that decides between them

The login is the hard part of this tool, and the README is more explicit about it than most projects are about anything.

If you log in to Evernote, OAuth is used, and the method is chosen with --oauth-method.

The default is desktop, which uses the same workflow as the Evernote Desktop Client. After you authorize in the browser, you cancel the redirect when the site asks to open the OAuth link and instead copy and paste that URL, the Return to Evernote one, into the evernote-backup terminal window. The stated limitation is sharp: the Evernote free plan allows only one active session at a time, so this may sign you out of an existing desktop or mobile client session or later ask you to disconnect this client.

That is a real constraint, and it is the kind that turns a five minute install into an afternoon of logging back into your phone.

The import method imports an OAuth session from an existing Evernote Desktop Client installation, which lets you run the Desktop Client in parallel with evernote-backup. It works as long as the Desktop Client stays logged in, and if you log out there, the refresh token is invalidated. It is supported on Windows and macOS.

The mcp method uses the Evernote MCP interface API. It is available only on paid Evernote plans and the README marks it as untested. It starts a local callback listener, and for headless or remote sessions you paste the full http://.../oauth_callback?code=... URL from the redirect into the terminal.

For Yinxiang, the --backend china option prompts for account credentials, and you can supply them beforehand with --user and --password. OAuth is not supported for Yinxiang, which is the clearest statement in the README that the two backends are not symmetric.

Sync is incremental, and it is where the API calls go

The sync step is where the Evernote Cloud API is used, and the README describes what it does with the sync state.

The tool keeps track of the sync state and downloads only new changes that have been made since the last run, so every sync will go pretty fast, but you will have to wait for a bit on the first run if you have a lot of notes in your account.

Interruption is handled explicitly. You can interrupt the process at any point, and it will continue from where it was left off when you rerun evernote-backup sync.

The output of a sync shows the shape of the work.

console
$ evernote-backup sync
Syncing latest changes...
  [####################################]  6763/6763
566 notes to download...
  [####################################]  566/566
Updated or added notebooks: 23
Updated or added notes: 566
Expunged notebooks: 0
Expunged notes: 0
Synchronization completed!

The expunged counts are the interesting part, because they are what makes the tool safe to run repeatedly. Expunged in Evernote means deleted, and the database tracks that, so the local copy mirrors the remote state rather than accumulating records that no longer exist upstream.

There is also a section on tasks, reminders and single-note shares that the README truncates, which is the area where a backup tool has to make a decision about non-note content. A task is not a note, so it does not obviously belong in a *.enex export, and how the tool handles that is exactly the sort of thing to check before relying on the export for a full account restore.

Install routes for four platforms, and a distroless container

The packaging is thorough, and the primary language is Python with a floor of 3.11.

The recommended route on Linux and Windows is uv.

console
uv tool install evernote-backup

Homebrew is the recommended route on macOS, with scoop, chocolatey and winget also covered for Windows, plus a portable binary download from the releases page and an install from source with uv.

The Docker route is the one with a wrinkle worth reading. The image runs from gcr.io/distroless/python3-debian12, which means there is no shell in the container at all, and the entrypoint is the evernote-backup binary itself. The build stage is debian:12-slim with a virtualenv, and uv is installed with pip3 install --break-system-packages uv.

Because the OAuth desktop method needs a local callback, the Docker instructions require forwarding port 10500, and the Dockerfile exposes it.

console
docker run --rm -t -v "$PWD":/tmp -p 10500:10500 vzhd1701/evernote-backup:latest init-db

The working directory is /tmp, which is why the volume mount is there, and the database lands in the mounted directory rather than inside the container. That is the detail that matters for a backup tool: the data has to survive the container.

The dependency pins tell you what the sync actually uses

The dependency list in pyproject.toml is short, pinned exactly, and the pins explain the implementation.

evernote-plus at 1.28.1.dev2 is the Evernote API client, and the .dev2 suffix on a pinned release is a signal that the project tracks a development build of its own client.

thrift at 0.21.0 is the protocol Evernote's own SDK uses, requests-oauthlib at 2.0.0 handles the OAuth flow, and requests-sse at 0.5.3 is for server-sent events, which is how the Evernote API streams changes during a sync. xmltodict at 1.0.4 converts the XML responses, and click at 8.4.2 with click-option-group at 0.5.9 builds the command line interface.

The last two dependencies are conditional on the platform: pycryptodome and keyring are listed with a marker for sys_platform equal to darwin or win32. That is the macOS Keychain and the Windows Credential Manager integration, so on those platforms the OAuth token can be stored in the operating system's credential store rather than a file, and on Linux it is not installed, where the keyring story depends on the desktop environment providing a usable secret service.

pyjwt at 2.13.0 handles the token encoding. The licence is MIT with the file listed under license-files, the project version is 1.14.0, and the entry point is evernote-backup = evernote_backup.cli:main.

The release history shows 1.14.0 from 2026-08-05, 1.13.1 from 2025-04-23, and a continuous development build from 2026-09-22, so the project is still being worked on.

Where the tool stops

The limits are mostly limits of Evernote itself rather than of the implementation, and it is worth being clear about them.

It is a one-way backup. Notes come down and files come out; nothing goes back up. A tool that mirrored your edits back into the Evernote account would be a different project with a different risk profile, and this one deliberately does not do that.

It needs a working login. The Evernote free plan allows only one active session, so the default OAuth method can displace your phone or desktop client, and the import method requires the desktop client to stay logged in. The mcp method is marked untested and is limited to paid plans.

It does not cover everything a note can hold. The README's section on tasks, reminders and single-note shares is truncated, and those are content types that a *.enex export handles differently from ordinary notes. Whether your export is a complete archive of your account depends on answers this README does not give.

Yinxiang has no OAuth path at all, and requires credentials to be entered or passed on the command line, which is a different security posture from a browser consent flow.

The repository also carries a SIMILAR_PROJECTS.md, which is the right place to look for the alternatives if any of these limits bite, and a CHANGELOG.md plus a justfile whose changelog target uses conventional-changelog.

Editorial conclusion

evernote-backup suits anyone who wants their Evernote or Yinxiang notes in a local, portable form, because the sync is incremental, the database is yours, and the export runs offline with no API access. It is the wrong tool if you want a live two-way sync, since the design is one-way backup and export, and it is the wrong choice if your Evernote account has no local client session, because the import OAuth method depends on the desktop client staying logged in. Before you start, decide which OAuth method you will use, since the Evernote free plan allows only one active session and the default desktop method can sign you out of your other clients.

Frequently asked questions

How do I export all my Evernote notes with evernote-backup?

Run three commands: evernote-backup init-db to initialise the database and authenticate, evernote-backup sync to download the notes into the local SQLite database, and evernote-backup export output_dir/ to write the .enex files. The export step runs wholly offline.

Which OAuth login methods does evernote-backup support for Evernote?

Three, selected with --oauth-method: desktop, which is the default and follows the Evernote Desktop Client workflow, import, which imports an OAuth session from an existing Desktop Client installation on Windows and macOS, and mcp, which uses the Evernote MCP interface API, is limited to paid plans and is marked untested.

Does the Evernote free plan cause problems with evernote-backup?

Yes. The README states the Evernote free plan allows only one active session at a time, so the default desktop OAuth method may sign you out of an existing desktop or mobile client session or later ask you to disconnect this client.

How do I export individual Evernote notes rather than one file per notebook?

Use the --single-notes flag to extract each note as a separate file, and add --include-trash if you also want trashed notes included in the export.

Can evernote-backup sync with Yinxiang as well as Evernote?

Yes, using the --backend china option, which prompts for account credentials or takes them from --user and --password. The README states OAuth is not supported for Yinxiang.

Official sources

  1. Issues
  2. License: MIT
  3. README
  4. Releases
  5. vzhd1701/evernote-backup on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/vzhd1701-evernote-backup.svg)](https://hysenlabs.com/projects/vzhd1701-evernote-backup)

Was this useful?