← All work
MARKETPLACES & CONSUMERIN DEVELOPMENTKittyBooksTurn fanfiction into audiobooks
Marketplaces & consumerIn developmentkarkittytron.com

KittyBooks

Turns fanfiction (from a link, pasted text, or an epub or txt file) into continuous, seekable audiobooks narrated by a self-hosted, open voice engine, so a long story can be listened to instead of read.

68 voices
self-hosted narration voices, no per-word fee
Gapless
chapters stitched at the sample level, fully seekable
~4.4s
to first playable audio, measured in production

The problem

Fanfiction is enormous, serialized and almost always text-only, often spread across many chapters and more than one site. Readers who'd rather listen (on a commute, or with tired eyes) have no clean way to turn an arbitrary story into a continuous, seekable audiobook, and commercial text-to-speech bills by the word, which doesn't suit long, casual reading. KittyBooks set out to close that gap with a self-hosted, open voice engine so narration carries no per-word cost.

What it does

You bring a story in from a link, pasted chapter text, or an epub or txt file, choose a voice, and KittyBooks narrates it into audiobook chapters you can play, scrub, and follow along with as the text highlights.

The narration engine is the real heart of it. It splits a chapter into sentences, narrates each one through the self-hosted voice engine, stitches the audio together at the sample level so there are no gaps between them, records where every sentence falls, and encodes a single seekable file per chapter. That one timing map drives gapless playback, the follow-along highlight, and tap-to-seek down to the sentence.

It's built to run on the studio's own hardware. The voice engine is open and self-hosted, so making an audiobook costs compute rather than a per-word fee, and the voice catalogue offers dozens of narration voices with samples to preview.

Key features

  • Import from a link, paste, or a file

    Bring a story in from a fan-fiction link, pasted chapter text, or an epub or txt upload.

  • Gapless, seekable chapters

    Each chapter is one real audio timeline you can scrub, stitched at the sample level rather than glued together in the browser.

  • Follow along, tap to seek

    The text highlights as narration plays and tapping a paragraph jumps straight there, driven by a per-sentence timing map.

  • Dozens of self-hosted voices

    A choice of narration voices with no paid text-to-speech bill, because the voice engine runs on the studio's own server.

  • Whole multi-chapter works

    It can walk a story's chapter links to assemble a long, serialized work rather than a single page.

  • Offline listening

    Chapters can be downloaded to play without a connection, on the web app or on the phone.

Where it stands

This is real, deployed engineering shown honestly as work in progress, not a finished product. As of the last working session the owner judged the overall effort a shortfall: the phone app hadn't run cleanly on his device and his own book hadn't narrated for him, so the pieces here are proven in code and on test accounts rather than polished for an everyday reader. The recorded next step is to rebuild the phone app on a proven foundation.

Under the hood: for the technically-minded

How it's built

It's a monorepo split by responsibility: an API over Postgres, a background worker that runs the narration queue, a React Router 7 web app, a React Native phone app, and shared packages for the data contract, the design tokens and the audio pipeline. Narration sits behind a single voice-engine interface whose one implementation talks to a self-hosted, open text-to-speech server, so narration carries no per-word cost.

The render path is the core: split a chapter into units, narrate each, concatenate the raw audio at the sample level while recording each unit's start time, build a timing map, then encode a single seekable file (switching to a streamed format for very long chapters) and store it for byte-range playback. That single timing artifact is what powers gapless audio, follow-along and tap-to-seek at once.

The design system is built on OKLCH colour tokens with a deliberate cool fandom-blue accent, a rule enforced in the build itself (it fails on any warm-hued colour), plus a per-book accent sampled from the book's cover with lightness and chroma fixed so every book clears the same contrast bar.

The hard problems

  • Gapless audio from an engine with no timings

    The voice engine returns audio but no timing information. The pipeline narrates unit by unit and captures each one's start offset as a by-product of stitching the raw audio together, producing a single timing map that serves playback, follow-along and tap-to-seek.

  • First-audio latency on CPU-only narration

    Self-hosted narration on CPU renders slower than real time, so a naive approach made listeners wait a minute or more. A two-phase encoder that publishes short opening segments first cut the measured time-to-first-audio to a few seconds.

  • Verified in tests, but not yet in the owner's hands

    The retrospective is candid: much of this was proven by automated tests and on the builders' own accounts while the owner's real devices kept hitting failures, from phone sign-in to a book stuck at zero percent to a desktop error. The honest lesson recorded was to rebuild the phone app on a proven foundation rather than from scratch, and to test on the real user's account throughout.

Built with

  • React Router 7
  • Fastify
  • Kokoro TTS (self-hosted)
  • Postgres
  • FFmpeg
  • Expo / React Native

Building something in this space?

Work with us →