Skip to main content

Markwell — back up and export your Kobo highlights and notes to Markdown, JSON, CSV, Anki TSV, and HTML.

Project description

Markwell

English · 中文(台灣) · 日本語 · 한국어

Mark well what you read. Back up and export your Kobo highlights into a corpus you own.

CI Downloads PyPI PyPI downloads

Safely back up, read, and export your Kobo highlights and notes — readable pages in your browser, plus Markdown, JSON, CSV, Anki flashcards, and a printable HTML library. Everything stays on your computer: no account, no cloud service, no network connections. Cross-platform, zero dependencies (Python standard library only).

The Library view: your books as cards, every highlight searchable

Get Markwell

Download the app for your computer from the latest release:

Unzip it and open the app: Markwell opens in your web browser, running entirely on your own computer.

If your computer hesitates at first launch — the download is unsigned

Markwell is free software and the downloads carry no code-signing certificate, so your operating system asks for one extra confirmation the first time:

  • macOS — right-click (or Control-click) Markwell and choose Open, then click Open in the dialog. macOS remembers your answer, so this is only needed once.
  • Windows — when the SmartScreen window appears, click More info, then Run anyway.

If you'd rather not run an unsigned binary, install the Python package below instead — the same app, with no bundled executable.

Prefer the command line? Markwell is also a Python package (Python 3.9+):

pipx install markwell    # or: pip install markwell
markwell                 # the command-line tool
markwell-gui             # the same app the desktop download runs

Why

Your highlights and notes are the irreplaceable part of your reading. Markwell:

  • Never writes to your device. It only ever reads the Kobo database, copying the file to a local snapshot. Nothing — not even SQLite housekeeping — touches the device.
  • Keeps every snapshot as immutable history. Each run saves a timestamped KoboReader-<stamp>.sqlite that is never overwritten, so you accumulate a full history of your reading database.
  • Gives you portable output. Human-readable Markdown, a documented JSON file, CSV for spreadsheets, Anki flashcards, and a self-contained HTML library — feed them into Obsidian, Anki, Excel, Readwise, or your own scripts.

The exports always mirror the latest snapshot only — they are a fresh projection of one database, not a growing archive. So if you delete a highlight on the device, it disappears from the next export. To recover it, re-export from a dated snapshot:

markwell --db backups/KoboReader-<stamp>.sqlite

The app (no terminal needed)

The desktop downloads above open straight into the app; from a terminal, it is:

markwell-gui          # or:  python3 -m markwell.gui

It opens in your web browser and lets you, in plain language:

  • Back up — one button snapshots your Kobo and turns your highlights into readable pages, with live progress and a clear result.
  • Library — read and search your highlights and notes in a calm, book-like view (one file per book, in reading order, with your notes).
  • Review — each day brings back one line from your highlights, with a shuffle and a per-book filter.
  • History — see every saved copy, re-create your files from an older one, and open the folder where everything lives.
  • Settings — choose where your library lives (a cloud folder, if you like) and pack everything into a single ZIP archive.

The Back up view: one button, a clear promise, live progress

It uses the same safe core as the command line, so it never writes to your Kobo. The app is purely local: it serves only to 127.0.0.1, makes no network connections, and requires a per-launch token on every request (see SECURITY.md). Files default to ~/Markwell — move them from Settings, or pass --data-dir — and the app always shows you where they are. It needs only the Python standard library — no extra dependencies, no build step.

Review & share cards

Each day the Review view brings back one line from your own highlights — the same line until tomorrow — with a shuffle and a per-book filter when you want more. And any highlight can become a share card: an image in three sizes and three styles, with CJK-aware typography and an optional watermark. Cards are drawn on a local canvas; nothing leaves your machine.

The Review view: one line a day, returning from your own highlights

A book's highlights in reading order, with your notes beneath

Your data, your languages

The whole interface speaks English, 繁體中文, 日本語, and 한국어 — switch languages from the sidebar; the choice is remembered. Exports are localized too: the scaffolding of the Markdown and HTML files — titles, counts, table headers — is written in your language. The app passes your interface language along automatically; the command line takes --lang en|zh-TW|ja|ko. Your highlights and notes themselves are always verbatim, never translated.

CSV and Anki column headers (and JSON keys) deliberately stay English: they are machine-facing identifiers, and tools like Notion or Anki map fields by those exact names — translating them would break every import recipe.

Back up to your cloud

Everything Markwell saves lives in one ordinary folder. Open Settings, pick iCloud Drive, Google Drive, Dropbox, or OneDrive, and Markwell copies your library there — nothing is ever deleted, and Markwell itself never uploads a byte: your cloud app syncs the folder like any other. The same screen can pack everything into a single ZIP archive. Step-by-step instructions — including moving to a new computer — are in the cloud backup guide.

Command line

Plug in your Kobo, then:

markwell                 # snapshot the device, then export every format
markwell --format md     # one format: md, json, csv, anki, or html
markwell --format md,csv # any comma list of those ("all" = every format)
markwell --lang ja       # language for export labels: en, zh-TW, ja, ko
markwell --snapshot-only # just back up the database, no export
markwell --db PATH       # export from an existing snapshot (no device read)
markwell --device PATH   # Kobo mount point OR KoboReader.sqlite path (overrides auto-detect)
markwell --require-device # fail instead of falling back to the latest local snapshot
markwell --out DIR       # output directory (default: output/, relative to the current directory)
markwell --debug         # show full tracebacks on error
markwell --version       # print the version and exit

Progress and status messages go to stderr; the exported data and JSON are written to files under --out. On success the tool prints the absolute path of the output directory, so you always know exactly where the files landed.

Output (backups/ and output/ are created relative to the current directory):

backups/
└── KoboReader-YYYYMMDD-HHMMSS.sqlite   timestamped, never overwritten
output/
├── index.md            all books, counts, links
├── <book>.md           one file per book, highlights in reading order
├── highlights.json     machine-readable export (schema "markwell/1")
├── highlights.csv      one row per highlight, for Excel / Numbers / Notion
├── anki.tsv            flashcards ready to import into Anki
└── library.html        the whole library as a single self-contained page

How it works

detect device → snapshot once (read-only) → read snapshot → render the chosen formats

The device is read at most once per run and never modified. The exports are a projection of the latest snapshot only; it is the snapshot history that preserves everything, so a highlight removed on the device is still recoverable from the dated .sqlite it was last captured in (see Why).

JSON format

{
  "schema": "markwell/1",
  "generator": "markwell/0.2.0",
  "generated": "2026-06-01",
  "source": "KoboReader-20260601-101010.sqlite",
  "source_freshness": "device",
  "books": [
    {
      "title": "…", "author": "…", "volume_id": "…",
      "highlights": [
        { "text": "…", "note": null, "date": "2025-03-17", "chapter_index": 4 }
      ]
    }
  ]
}

Fields:

  • schema — the schema contract, markwell/<MAJOR> (see below).
  • generator — the producing tool and its version, markwell/<version>.
  • generated — local date (YYYY-MM-DD) the export was produced.
  • source — filename of the snapshot the export was projected from.
  • source_freshness — whether source came from a live "device" snapshot taken this run, or a "cached_snapshot" reused because no device was connected.
  • books[] — each with title, author, volume_id, and highlights[] (text, note, date, chapter_index).

Schema stability

The /N suffix in schema is the major version. It only bumps on a breaking change (a field removed, renamed, or given a new meaning). Within a major version, changes are additive only — new fields may appear, so consumers must ignore unknown fields rather than failing on them. Pin to the major (markwell/1) and you can rely on every documented field staying put.

Exit codes

Code Meaning
0 success
2 no device and no usable snapshot/source
3 database read fine, but contained no highlights or notes
4 source unreadable or its schema is unsupported

Notes & compatibility

  • Tested against Kobo firmware schemas with Bookmark and content tables. If a firmware update changes the schema, please open an issue.
  • Note (annotation) support reads Bookmark.Annotation; if you write notes on highlights, they appear under each highlight.
  • Exported text is verbatim and untrusted. Highlights and notes are reproduced exactly as written, so treat the Markdown/JSON as data, not trusted markup — a value beginning with =, +, -, or @ can be read as a formula if you import it into a spreadsheet/CSV, so sanitize on import if that matters. See SECURITY.md.

Development

pip install -e ".[dev]"
pytest

See CONTRIBUTING.md for the architecture invariants and house rules, CHANGELOG.md for what's changed, and SECURITY.md for how to report a vulnerability.

Maintainer

Built and maintained by Eric Tu (@ceparadise168) — ceparadise168@gmail.com. Markwell is free, with no donations accepted for now — if it helped you preserve your reading, star the repo and share a quote card.

License

MIT — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

markwell-0.2.0.tar.gz (141.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

markwell-0.2.0-py3-none-any.whl (116.0 kB view details)

Uploaded Python 3

File details

Details for the file markwell-0.2.0.tar.gz.

File metadata

  • Download URL: markwell-0.2.0.tar.gz
  • Upload date:
  • Size: 141.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for markwell-0.2.0.tar.gz
Algorithm Hash digest
SHA256 6ae3c75387b17701d5912e5c5a5e474ecb6a107990db30033c676c7843ea4407
MD5 5be43a4cd2d327d41fb84cb6b1cd8698
BLAKE2b-256 b56b11b84a34a9f6fc69531d7769ecbde95f2f9e18b03e9e5c2d7ec4bc5f4d4e

See more details on using hashes here.

Provenance

The following attestation bundles were made for markwell-0.2.0.tar.gz:

Publisher: publish-pypi.yml on ceparadise168/markwell

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file markwell-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: markwell-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 116.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for markwell-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 5d27cc2df1a16509248c5a7e8e2d5191107c819ebd2e2c270955d30e13cca196
MD5 99c17cab9d793ab370332e40dc8ac0f7
BLAKE2b-256 8024f531746e76c6637550713f4d497b5a447d2b777ebfd11a3d9db63d6e1e1c

See more details on using hashes here.

Provenance

The following attestation bundles were made for markwell-0.2.0-py3-none-any.whl:

Publisher: publish-pypi.yml on ceparadise168/markwell

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page