Hamlet in development

Your audiobooks, podcasts and ebooks, on your own machine.

Hamlet is a self-hosted media server for audiobooks, podcasts and ebooks. Point it at a folder of files, and it gives you a web client with chapters, playback positions, and real-time library updates, all running on your hardware, under your control.

It's in active development. The server works, the web client works, and the rough edges are mostly in the gap between "runs on my machine" and "runs on yours."

View on GitHub Self-hosted · Docker or bare Node.js

What it does

Hamlet scans your media folders, extracts metadata and cover art with FFmpeg, and serves a web client you open in any browser. No app to install on every device. Just a URL.

Scans your existing files

Point Hamlet at directories of audiobooks, podcasts and ebooks. It reads chapter markers, durations and embedded cover art from the files themselves. No manual importing, no file renaming.

A web client that stays out of the way

A single-page web client served from the same process. Chapter-aware playback, adjustable speed, a sleep timer, an in-browser ebook reader, and your position kept per book, per show and per read, from any browser on any device on your network.

Real-time library updates

Drop a new file into a watched folder and Hamlet picks it up. The client gets a live update via server-sent events. No polling, no page refresh, no waiting for a scheduled scan.

Runs on your hardware

A single Node.js process with a SQLite database. No cloud dependency, no external services, no telemetry. Everything lives on the machine you run it on, and nothing leaves it.

Podcasts, properly

Search and subscribe by feed, download episodes on a schedule, and let auto-download rules prune the oldest downloaded episodes so a backlog doesn't quietly fill the disk.

Reads ebooks too

EPUB and plain text open right in the browser, with a reading position tracked separately from anything you're listening to. An audiobook and its companion ebook can share one library entry.

The stack

Deliberately boring choices. One process, one database file, standard tools.

LayerRoleChoice
Server Core Node.js + TypeScript + Fastify. One process serves the API, the client, and cover art.
Database Core SQLite via Drizzle ORM. A single file at ./data/shelf.db. Back it up by copying it.
Media probing Core FFmpeg and ffprobe on PATH. Extracts duration, chapters, and embedded cover art from your files.
Live updates Core Server-Sent Events. No WebSocket complexity, works behind reverse proxies without configuration.
Podcasts & ebooks Core fast-xml-parser for RSS feeds and EPUB metadata, adm-zip for EPUB containers, node-cron for scheduled auto-downloads, epub.js (client-side) for in-browser reading.
Auth Infra JWT access tokens (24h), argon2 password hashing. Bearer auth on all API routes.
Deployment Infra Dockerfile included (node:20-slim + ffmpeg). Docker Compose with volume mounts for /audiobooks and /podcasts, or run bare with npm run dev.

Roadmap

In order, not on a schedule.

Tap a milestone for the details.

A Docker image and a GitHub repo you can clone, point at your media, and open in a browser. The scanner, API, web client, auth, podcasts and ebook reading are all already working end-to-end. What's left is packaging, plus the kind of edge cases that only show up on someone else's machine.

What "done" looks like docker compose up, open localhost:3000, create an account, and your audiobook, podcast and ebook library is there with chapters, covers and reading position. Playback position syncs across tabs and devices.

MOBI and AZW3 files already show up in your library and get catalogued with the rest of your ebooks; actually reading them in-browser is next, the same way Leaflet already does on Android.

What "done" looks like Open an .mobi or .azw3 file from Hamlet's web client the same way you'd open an EPUB: chapters, reading position, everything, on any device with a browser.

Questions

What do I need to run it?
A machine that can run Docker (or Node.js 20+ with FFmpeg installed). A Raspberry Pi works. A NAS works. A VPS works. If it runs containers, it runs Hamlet.
What file formats does it support?
Anything FFmpeg can probe, which is nearly everything. M4B with embedded chapters is the best experience; folders of MP3s work too, with each file treated as a chapter. FLAC, OGG, M4A, and AAC all play through the browser's native audio.
Does it handle ebooks too?
Yes. EPUB and plain text open right in the browser's reader, with their own reading position tracked separately from anything you're listening to. MOBI and AZW3 files are catalogued and show up in your library, but reading them isn't wired up yet (it's on the roadmap).
How does it work with Wavelet?
They connect. Point Wavelet at your Hamlet server and log in, and your library, downloads and playback position come from Hamlet instead of living only on the phone. Wavelet becomes Hamlet's mobile client. Prefer everything local? Wavelet works standalone too, and Hamlet's web client works in any browser without installing anything.
Can multiple people use the same server?
Yes. Each user gets their own account, their own playback positions, and their own library progress. The files are shared; the state is per-user.
Why "Hamlet"?
A small home for your media. Also, a building with columns and a glowing doorway made for a nice icon.
Hamlet emblem

Leave the light on.

Hamlet is self-hosted and in active development. Audiobooks, podcasts, and now ebooks too. Point it at your files and open your browser.

Hamlet · a Letworks project · siblings: Leaflet · Wavelet · Trust & Security · built with Node.js, TypeScript & Fastify