Hamlet in development

Your whole library, on a machine you control.

Hamlet is a server you run yourself for your books, audiobooks and podcasts. Point it at your folders and it reads the files. Leaflet and Wavelet sign in to it, pull from it, and keep your place in step. No cloud in the middle, no one else's terms.

It's in development. The server works, and Leaflet and Wavelet already talk to it. The rough edges are mostly in the gap between "runs on our machine" and "runs on yours".

See the roadmap In development · no public build yet · Docker or Node.js
compose.yml · an example, not the shipped file
services:
  hamlet:
    build: .  # FFmpeg inside
    volumes:
      - ~/Books:/media/books
      - ~/Audiobooks:/media/audiobooks
      - ~/Podcasts:/media/podcasts
      - ./data:/data  # one SQLite file
    ports:
      - "PORT:PORT"  # HTTPS in front
  • 1 process
  • 1 SQLite file
  • FFmpeg probing
  • Live updates over SSE

What it does

The other apps keep your library on one device. Hamlet keeps it on a machine you own, and serves it to every device you use.

Reads your existing files

Point Hamlet at folders of books, audiobooks and podcasts. It reads chapters, durations and cover art from the files themselves. No importing by hand, no renaming.

The apps already speak it

Leaflet and Wavelet connect to Hamlet today. Browse the server's library, download what you want onto your phone, and your place, bookmarks and progress sync back when you're done.

One server, several people

The first account you create is the admin. Everyone else gets their own sign-in, their own positions and their own progress. The files are shared. The state is per person.

Runs on your hardware

It needs no cloud service and sends no telemetry. Everything lives on the machine you run it on, and nothing leaves it unless you set it up to. It's the "yours to keep" rule, all the way down.

The stack

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

LayerRoleChoice
Server Core Node.js + TypeScript + Fastify. One process serves the API and the cover art.
Database Core SQLite via Drizzle ORM. A single file, which you back up by copying it.
Media probing Core FFmpeg and ffprobe. Reads duration, chapters and embedded cover art from your files.
Live updates Core Server-Sent Events. No WebSocket complexity, and it works behind a reverse proxy.
Auth Infra Expiring access tokens and hashed passwords. Every API route needs a signed-in user.
Deployment Infra A Dockerfile with FFmpeg included, and Docker Compose with your media folders mounted as volumes. Or run it on bare Node.js.

Roadmap

Listed in order, with no dates.

Open a milestone for the details.

This used to be the "further out" milestone. It landed early. Leaflet and Wavelet sign in to your server, browse it, download from it, and sync your place back.

What "done" looked like Download a book onto your phone, listen on the train with no signal, and have the server know where you stopped once you're back online.

A Docker image anyone can pull, point at their media, and run. Setup, scanning, accounts and sync all working end to end on hardware that isn't ours.

What "done" looks like docker compose up, create the admin account, connect Leaflet or Wavelet, and your library is there with chapters and covers.

Hamlet already serves the podcast episodes it holds. Next, it follows feeds itself, so new episodes land on your server without a phone doing the fetching.

What "done" looks like Add an RSS URL once, Hamlet fetches and stores new episodes on your server, and every app you connect sees them.

Questions

What do I need to run it?
A machine that can run Docker, or Node.js with FFmpeg installed. A Raspberry Pi, a NAS or a small VPS will do. If it runs containers, it runs Hamlet.
What file formats does it handle?
For audio, anything FFmpeg can read, which is nearly everything. M4B with embedded chapters is the best experience. Folders of MP3s work too, with each file treated as a chapter. Ebooks are served as the files they are, for Leaflet to open.
How is it different from Wavelet?
Different job. Wavelet is the player in your pocket, offline-first and personal. Hamlet is the shelf at home that holds everything and serves it to whichever device you pick up. Wavelet works fine without Hamlet. With it, your place follows you.
Is it open source?
Not yet. The licence hasn't been decided for any of the Letworks apps, and we'd rather decide it properly than announce it early. When it's settled, it'll say so here.
Why "Hamlet"?
A small home for your media. Also, a building with columns and a glowing doorway made for a nice icon.