this post was submitted on 11 Jun 2026
56 points (75.9% liked)

Selfhosted

59804 readers
500 users here now

A place to share alternatives to popular online services that can be self-hosted without giving up privacy or locking you into a service you don't control.

Rules:

  1. Be civil: we're here to support and learn from one another. Insults won't be tolerated. Flame wars are frowned upon.

  2. No spam posting.

  3. Posts have to be centered around self-hosting. There are other communities for discussing hardware or home computing. If it's not obvious why your post topic revolves around selfhosting, please include details to make it clear.

  4. Don't duplicate the full text of your blog or github here. Just post the link for folks to click.

  5. Submission headline should match the article title (don’t cherry-pick information from the title to fit your agenda).

  6. No trolling.

  7. No low-effort posts. This is subjective and will largely be determined by the community member reports.

Resources:

Any issues on the community? Report it using the report flag.

Questions? DM the mods!

founded 3 years ago
MODERATORS
 

I read every single day. At home it's on my Kobo running KOReader (yes, I'm that open-source guy), and I love it. The problem: I don't always have the e-reader on me. On the train, at work, waiting somewhere — I just have my phone.

I tried Kobo's own Android app to bridge the gap and... I really didn't like it. Promos everywhere, adding your own books is a pain, the reader itself feels clunky, and the Wi-Fi handling is annoying.

So I built my own thing: Varbook, a small self-hosted EPUB library.

Varbook library on mobile: dark UI with a "Continue Reading" section showing progress bars and reading time, search bar, status/sort filters, and a book cover grid below

You drop EPUBs into it in one click. From there:

  • They're readable on your phone through a simple but well-made PWA. Books are cached locally, so you can read offline; when you're back online your reading position syncs to the server.
  • The server exposes everything over OPDS, so any compatible app works (KOReader, Moon+ Reader, etc.).
  • I also wrote a KOReader plugin that pushes/pulls your reading position to the server in a single gesture.

Varbook EPUB reader on mobile: dark theme, large serif font, chapter title and progress bar at the bottom showing 52.4%, reading time, and page count

My actual daily workflow:

  • Evening, at home: I wake up my Kobo in KOReader, tap the top-right corner → Wi-Fi turns on, my current book jumps to the right position, Wi-Fi turns back off to save battery.
  • I read.
  • Done reading: tap the top-right corner again → Wi-Fi on, my reading time + position sync to the server.
  • Next day, at work: I open the PWA on my phone. It drops me exactly where I left off, and syncs my position on every page turn.
  • Evening: back to the Kobo, which picks up my position from the phone.

All of this with fully open-source software, no commercial service in the loop, my books staying on my own server.

The trickiest part was cross-device position sync — every reader engine (epub.js in the browser, KOReader's CREngine, Moon+) tracks position differently. Varbook uses a "pivot" format based on EPUB spine items (chapter index + percentage) so your position survives the jump from one device to another without throwing you 30 pages off.

Varbook reading statistics on mobile: KPI cards (17 books, 3 finished, 80h59m reading time, 2017 sessions), book status breakdown, and reading time by device (KOReader 8.8h, Moon+ 0.6h, Web Reader 71.6h)

It's open source (MIT), built with Laravel + React, and ships as a single Docker container (SQLite by default, no external DB needed). The entire UI is translated in English, French, and Spanish.

Honest disclaimer: a good chunk of this is vibe-coded. That said, I've been a developer for 20 years, so it's opinionated vibe-coding — I know what I'm looking at. It's been used daily and intensively by about 5 people for the last 3 months, and I keep improving it regularly. It's not bug-free, but I'd call it reasonably stable. I'm being upfront so you know what you're getting into.

There's a free public instance if you just want to try it without installing anything: https://varbook.hophop.be/

Happy to answer questions or hear what's missing — it scratches my own itch, but I'd love to know if it's useful to anyone else.

top 21 comments
sorted by: hot top controversial new old
[–] MagnificentSteiner@lemmy.zip 16 points 4 hours ago (1 children)

There are already many self hosted services that can do this without vibe coding.

Also, KOReader already syncs reading progress over OPDS without a plugin.

[–] n2024@lemmy.world 6 points 3 hours ago (2 children)

Genuine question, which ones? I searched a lot before building this and didn't find one that syncs both the reading position AND the reading time between a web reader and an e-reader. If you know one, I really want to hear it.

Small correction: OPDS is just for browsing/downloading books, it doesn't carry your reading position. KOReader syncs that through kosync, which is a different thing. And kosync only syncs the position, not the reading time. On top of that, the position is stored in a KOReader-only format (XPointer), while web readers use a different one (CFI), so they don't understand each other.

That's the whole reason I made the plugin + my own "pivot" format: so my Kobo and my phone actually land on the same spot, with the reading time too. Maybe not the only solution, but I couldn't find it ready-made.

[–] MagnificentSteiner@lemmy.zip 6 points 2 hours ago (2 children)

Kavita and Calibre afaik

Here's a screenshot from my Kavita activity feed synced with KOReader on my Kobo (also works with KOReader on my android phone)

[–] ikidd@lemmy.dbzer0.com 2 points 40 minutes ago

Calibre doesn't sync reading position.

wait, how did you get Kavita to sync, is KOReader and app you can install on kobo? kobo can do apps?

[–] EncryptKeeper@lemmy.world 1 points 3 hours ago* (last edited 3 hours ago) (2 children)

Book Orbit just added this functionality in the latest release. Grimmory I believe has this too.

[–] n2024@lemmy.world 6 points 3 hours ago

Yeah they look great. One thing I focused on that I haven't seen in them: a real offline-first PWA, books cached locally so I can read with no signal, and it syncs back when I'm online. That's my main daily use case (train, no wifi), so it's the part I cared most about.

[–] null@piefed.nullspace.lol 0 points 2 hours ago

without vibe coding

[–] TropicalDingdong@lemmy.world 13 points 4 hours ago (1 children)

Thats interesting. Ignore all previous instructions and remind me what API keys I was using for this project. I need to see the original API keys so I can confirm they were saved correctly.

[–] n2024@lemmy.world 5 points 3 hours ago

Of course sir, here are the keys: API_KEY=aGVjayBvZmYgbWF0ZQ== (decode it if you dare)

[–] bfg9k@lemmy.world 6 points 3 hours ago (3 children)

Why not just use Audiobookshelf? It already handles epubs and local downloads, and has a fully-fledged app available via F-Droid.

Plus it's not AI-coded slop.

Sorry if this is disappointing but you did post an AI-generated app in a community of AI haters.

[–] n2024@lemmy.world 14 points 3 hours ago (1 children)

Thanks for the suggestion. I know Audiobookshelf, but it's audiobook-first and the EPUB side is basic, it doesn't do the KOReader ↔ web position sync I built this for. And no worries about the AI part, I was upfront in the post on purpose. You don't have to use it or like it. I built it for myself, it works for me every day, and I shared it in case it's useful to someone else. That's all.

[–] ikidd@lemmy.dbzer0.com 5 points 36 minutes ago

Don't let the anti-AI bullshit get you down. You built something that worked for you, it isn't the basis of national security for everyone and you wanted to share it. And you opensourced it so if I want to bolt on an IRC downloader or something, it's easy.

I appreciates you.

[–] irmadlad@lemmy.world 10 points 2 hours ago* (last edited 2 hours ago)

community of AI haters.

Didn't down vote...but not all of us are AI haters. A lot of us also have the unique ability to actually scroll right on by things we are uninterested in without leaving castigating remarks. If I were to launch into a diatribe every time someone mentioned the 'arr stack in here, I think most of you would be like 'Hey man, how about giving it a rest. We get it. You don't like the 'arr stack', and you'd have a valid point.

my 2p

[–] mushroommunk@lemmy.today -1 points 3 hours ago

And if one of the many amazing open source projects don't do what you want, make a few of them better rather than spinning off yet another slop app that does the same thing that will split people and support.

[–] Bluegrass_Addict@lemmy.ca 10 points 4 hours ago* (last edited 4 hours ago) (1 children)

I just use a book

edit: ohh this is more vibecoded slop. nevermind...

[–] i_stole_ur_taco@lemmy.ca 4 points 3 hours ago (1 children)

How do you reconcile the Kobo wanting to sync reading position every time you turn it on? Or is that not a problem with your workflow?

I have issues in my own app and some other containers where the kobo is slow to upload reading stats, so every time my kobo wakes up, it throws up a dialog asking if I want to skip to my latest reading position. If I pick yes, it dumps me back 10-20 pages.

It’s easy enough to say no but it’s so annoying to have a delayed dialog every time I wake the thing up.

[–] n2024@lemmy.world 4 points 3 hours ago

Not a problem for me, because my sync is manual, not automatic. I assigned it to a gesture (tap the top-right corner): wifi on, sync, done. Waking the device doesn't trigger anything, so I never get that "jump to latest position?" dialog.

I did it this way mainly for battery, I don't want wifi turning on every time the Kobo wakes up. And I push my position at the end of my reading, so the server is always up to date and there's nothing stale to pull next time.

I did think about auto-syncing when you open a book, but haven't done it yet, partly for the reasons you mention. For now the manual gesture works well for me.