Seamless background sync for KOReader highlights, notes, bookmarks and precise reading progress across devices.
180
stars
313
commits
Lua
primary language
Sep 2, 2026
updated
Sync your KOReader annotations everywhere!
Never lose a highlight, note, bookmark, or reading progress again—AnnotationSync keeps your reading life in sync across all your devices.
[!WARNING] Reading Progress Sync requires KOReader 2026.07 or later, which includes the Cloud storage+ plugin. On older releases without this plugin, all progress sync options will be greyed out in the menu and a "Why are some options greyed out?" item will explain this in-app.
Core annotation sync works on both older and newer versions.
plugins directory (it must be named exactly AnnotationSync.koplugin).AnnotationSync supports two cloud integration methods, depending on your version of KOReader.
KOReader 2026.07 and later include a Cloud storage+ plugin that manages all your cloud accounts in one place. AnnotationSync integrates with it automatically.
Step 1 — Configure your provider in Cloud storage+:
Step 2 — Connect AnnotationSync:
By default, sync files are named after an MD5 hash of the document path. To use actual filenames instead (useful if you organize files with Calibre): Tools → Annotation Sync → Settings → Use filename instead of hash
On KOReader releases older than 2026.07, without the Cloud storage+ plugin, AnnotationSync uses KOReader's built-in SyncService.
[!NOTE] Reading Progress Sync and Cloud storage+ integration are unavailable before KOReader 2026.07. The "Why are some options greyed out?" menu item provides an in-app explanation.
Manual Sync — Immediately sync the current document's annotations and bookmarks (bidirectional merge). Runs regardless of whether the document has local pending changes.
Sync All — Mass-sync all documents that have pending local changes.
Sync All (including unread) — Scan your entire library for books with annotations that have never been synced (not just the ones AnnotationSync already knows are dirty) and sync them too. Useful for a first-time bulk sync, or after importing an existing library with pre-made annotations.
Automatic Syncing — Automatically run Sync All as soon as a network connection becomes available.
[!IMPORTANT] Understanding Sync All vs. Manual Sync
Sync All only processes documents that AnnotationSync has locally marked as changed ("dirty") on this device — i.e., books you annotated here since the last sync. It will not pull down changes that another device pushed to the cloud, because those documents are not in your local pending queue.
Manual Sync always performs a full bidirectional merge for the active document, regardless of local pending state. Use it when you want to fetch annotations that another device pushed for a book you haven't annotated locally.
Rule of thumb: Sync All = push your own offline work. Manual Sync = also pull what others pushed.
(Requires KOReader 2026.07+ with the Cloud storage+ plugin)
Bedside Kobo, Phone). Defaults to the hardware model name if left blank.Keep your KOReader settings (e.g., gestures, hotkeys, page overlap style) synchronized across devices.
[reader], [defaults], [settings/hotkeys]).[✓] indicates it will be synchronized:
[✓] [reader] page_overlap_style: default -> none
[ ] [settings/hotkeys] hotkey_map >
[!IMPORTANT] Exclusions & Failsafes The following settings are strictly excluded from synchronization to prevent credential leaks, sync loops, and device conflicts:
- Private credentials and server configurations (e.g.,
cloud_server_object, FTP/WebDAV passwords)- Device-specific identifiers and paths (e.g.,
device_id,device_name,lastfile,home_dir, font maps, cover caches)- Core plugin settings (e.g.,
annotation_sync_pluginandAnnotationSyncpreferences)- Database and statistics logs (e.g., battery stats, terminal configs, book statistics)
[!WARNING] Security Warning Synced settings are stored in cleartext (unencrypted JSON) on your cloud storage under
settings_sync.json. Avoid syncing sensitive or private configuration values.
AnnotationSync tracks deleted annotations so you can recover them:
AnnotationSync tracks all documents with local annotation changes pending sync:
All AnnotationSync actions can be bound to gestures or added to KOReader profile action lists via Settings → Taps and Gestures or the Profiles plugin:
| Action title | What it does |
|---|---|
| AnnotationSync: Manual Sync | Sync the active document's annotations |
| AnnotationSync: Sync All | Sync all locally-changed documents |
| AnnotationSync: Sync All (including unread) | Scan the library and sync every book with unsynced annotations |
| AnnotationSync: Push reading progress | Push the current page position to the cloud |
| AnnotationSync: Jump to device progress | Open the device progress selector |
| AnnotationSync: Push settings to cloud | Upload selected settings |
| AnnotationSync: Pull settings from cloud | Browse and import settings from another device |
Setting up Dropbox on KOReader can be a little bit difficult. This excellent post on the MobileRead forum explains the procedure in detail.
Koofr is a cloud storage provider that supports WebDAV. Connecting KOReader to Koofr via WebDAV requires a dedicated application password instead of your primary Koofr password.
KOReader), and click Generate.With Cloud storage+ (KOReader 2026.07+):
With the legacy SyncService (KOReader before 2026.07):
Connection details:
Koofr (or any name of your choice)https://app.koofr.net/dav/Koofr/koreader or /AnnotationSync — recommended to keep sync files in a dedicated directory. If you use a custom subdirectory, make sure it exists in Koofr before syncing.The project includes a comprehensive integration test suite. To run it, you need a KOReader development environment (kodev).
If you don't already have a built koreader checkout, or you're on a bare Debian/Ubuntu container without the toolchain:
run_tests.sh and the manual steps below assume this plugin lives at <koreader>/plugins/AnnotationSync.koplugin. If you've checked this repo out elsewhere, symlink it in rather than moving it:
ln -s /path/to/AnnotationSync.koplugin /path/to/koreader/plugins/AnnotationSync.koplugin
cmake, ninja-build, ccache, luarocks, and meson (easy to miss — koreader/base's CMake config fails with Could not find Meson without it; the official CI image has it preinstalled, so this step is invisible there). On Debian/Ubuntu, also install the SDL3 build deps listed in .github/workflows/test.yml (libx11-dev, libwayland-dev, libasound2-dev, etc.) if the emulator build fails to find them.base submodule (this is the only submodule the test suite needs — no full kodev build required):
cd /path/to/koreader
git submodule update --init --recursive base
make fetchthirdparty
make base
This compiles koreader-base's thirdparty C deps (mupdf, SDL3, sqlite, busted, …) — expect a long first run with no build cache../run_tests.sh <path_to_koreader>
The script compiles translations, automatically discovers all test suites in spec/unit/, links them into the KOReader spec/unit directory, and runs them via ./kodev test. Symlinks are cleaned up on exit.
Setup: Symbolically link test files into the KOReader core spec/unit directory:
cd /path/to/koreader
ln -s ../../plugins/AnnotationSync.koplugin/spec/unit/*.lua spec/unit/
Execute Tests: Run all tests or a specific suite:
./kodev test front <test_name>
Replace <test_name> with any *_spec.lua filename in spec/unit/, without the _spec.lua suffix (e.g. sync_integration, progress_sync_integration, settings_persistence).
Pull requests, feature suggestions, and bug reports are very welcome! Open an issue or submit a PR.
AnnotationSync.koplugin: Your reading notes, highlights, and bookmarks—always with you, always safe.
Lua
99.0%
Seamless background sync for KOReader highlights, notes, bookmarks and precise reading progress across devices.
180
stars
313
commits
Lua
primary language
Sep 2, 2026
updated
Sync your KOReader annotations everywhere!
Never lose a highlight, note, bookmark, or reading progress again—AnnotationSync keeps your reading life in sync across all your devices.
[!WARNING] Reading Progress Sync requires KOReader 2026.07 or later, which includes the Cloud storage+ plugin. On older releases without this plugin, all progress sync options will be greyed out in the menu and a "Why are some options greyed out?" item will explain this in-app.
Core annotation sync works on both older and newer versions.
plugins directory (it must be named exactly AnnotationSync.koplugin).AnnotationSync supports two cloud integration methods, depending on your version of KOReader.
KOReader 2026.07 and later include a Cloud storage+ plugin that manages all your cloud accounts in one place. AnnotationSync integrates with it automatically.
Step 1 — Configure your provider in Cloud storage+:
Step 2 — Connect AnnotationSync:
By default, sync files are named after an MD5 hash of the document path. To use actual filenames instead (useful if you organize files with Calibre): Tools → Annotation Sync → Settings → Use filename instead of hash
On KOReader releases older than 2026.07, without the Cloud storage+ plugin, AnnotationSync uses KOReader's built-in SyncService.
[!NOTE] Reading Progress Sync and Cloud storage+ integration are unavailable before KOReader 2026.07. The "Why are some options greyed out?" menu item provides an in-app explanation.
Manual Sync — Immediately sync the current document's annotations and bookmarks (bidirectional merge). Runs regardless of whether the document has local pending changes.
Sync All — Mass-sync all documents that have pending local changes.
Sync All (including unread) — Scan your entire library for books with annotations that have never been synced (not just the ones AnnotationSync already knows are dirty) and sync them too. Useful for a first-time bulk sync, or after importing an existing library with pre-made annotations.
Automatic Syncing — Automatically run Sync All as soon as a network connection becomes available.
[!IMPORTANT] Understanding Sync All vs. Manual Sync
Sync All only processes documents that AnnotationSync has locally marked as changed ("dirty") on this device — i.e., books you annotated here since the last sync. It will not pull down changes that another device pushed to the cloud, because those documents are not in your local pending queue.
Manual Sync always performs a full bidirectional merge for the active document, regardless of local pending state. Use it when you want to fetch annotations that another device pushed for a book you haven't annotated locally.
Rule of thumb: Sync All = push your own offline work. Manual Sync = also pull what others pushed.
(Requires KOReader 2026.07+ with the Cloud storage+ plugin)
Bedside Kobo, Phone). Defaults to the hardware model name if left blank.Keep your KOReader settings (e.g., gestures, hotkeys, page overlap style) synchronized across devices.
[reader], [defaults], [settings/hotkeys]).[✓] indicates it will be synchronized:
[✓] [reader] page_overlap_style: default -> none
[ ] [settings/hotkeys] hotkey_map >
[!IMPORTANT] Exclusions & Failsafes The following settings are strictly excluded from synchronization to prevent credential leaks, sync loops, and device conflicts:
- Private credentials and server configurations (e.g.,
cloud_server_object, FTP/WebDAV passwords)- Device-specific identifiers and paths (e.g.,
device_id,device_name,lastfile,home_dir, font maps, cover caches)- Core plugin settings (e.g.,
annotation_sync_pluginandAnnotationSyncpreferences)- Database and statistics logs (e.g., battery stats, terminal configs, book statistics)
[!WARNING] Security Warning Synced settings are stored in cleartext (unencrypted JSON) on your cloud storage under
settings_sync.json. Avoid syncing sensitive or private configuration values.
AnnotationSync tracks deleted annotations so you can recover them:
AnnotationSync tracks all documents with local annotation changes pending sync:
All AnnotationSync actions can be bound to gestures or added to KOReader profile action lists via Settings → Taps and Gestures or the Profiles plugin:
| Action title | What it does |
|---|---|
| AnnotationSync: Manual Sync | Sync the active document's annotations |
| AnnotationSync: Sync All | Sync all locally-changed documents |
| AnnotationSync: Sync All (including unread) | Scan the library and sync every book with unsynced annotations |
| AnnotationSync: Push reading progress | Push the current page position to the cloud |
| AnnotationSync: Jump to device progress | Open the device progress selector |
| AnnotationSync: Push settings to cloud | Upload selected settings |
| AnnotationSync: Pull settings from cloud | Browse and import settings from another device |
Setting up Dropbox on KOReader can be a little bit difficult. This excellent post on the MobileRead forum explains the procedure in detail.
Koofr is a cloud storage provider that supports WebDAV. Connecting KOReader to Koofr via WebDAV requires a dedicated application password instead of your primary Koofr password.
KOReader), and click Generate.With Cloud storage+ (KOReader 2026.07+):
With the legacy SyncService (KOReader before 2026.07):
Connection details:
Koofr (or any name of your choice)https://app.koofr.net/dav/Koofr/koreader or /AnnotationSync — recommended to keep sync files in a dedicated directory. If you use a custom subdirectory, make sure it exists in Koofr before syncing.The project includes a comprehensive integration test suite. To run it, you need a KOReader development environment (kodev).
If you don't already have a built koreader checkout, or you're on a bare Debian/Ubuntu container without the toolchain:
run_tests.sh and the manual steps below assume this plugin lives at <koreader>/plugins/AnnotationSync.koplugin. If you've checked this repo out elsewhere, symlink it in rather than moving it:
ln -s /path/to/AnnotationSync.koplugin /path/to/koreader/plugins/AnnotationSync.koplugin
cmake, ninja-build, ccache, luarocks, and meson (easy to miss — koreader/base's CMake config fails with Could not find Meson without it; the official CI image has it preinstalled, so this step is invisible there). On Debian/Ubuntu, also install the SDL3 build deps listed in .github/workflows/test.yml (libx11-dev, libwayland-dev, libasound2-dev, etc.) if the emulator build fails to find them.base submodule (this is the only submodule the test suite needs — no full kodev build required):
cd /path/to/koreader
git submodule update --init --recursive base
make fetchthirdparty
make base
This compiles koreader-base's thirdparty C deps (mupdf, SDL3, sqlite, busted, …) — expect a long first run with no build cache../run_tests.sh <path_to_koreader>
The script compiles translations, automatically discovers all test suites in spec/unit/, links them into the KOReader spec/unit directory, and runs them via ./kodev test. Symlinks are cleaned up on exit.
Setup: Symbolically link test files into the KOReader core spec/unit directory:
cd /path/to/koreader
ln -s ../../plugins/AnnotationSync.koplugin/spec/unit/*.lua spec/unit/
Execute Tests: Run all tests or a specific suite:
./kodev test front <test_name>
Replace <test_name> with any *_spec.lua filename in spec/unit/, without the _spec.lua suffix (e.g. sync_integration, progress_sync_integration, settings_persistence).
Pull requests, feature suggestions, and bug reports are very welcome! Open an issue or submit a PR.
AnnotationSync.koplugin: Your reading notes, highlights, and bookmarks—always with you, always safe.
Lua
99.0%