Skip to main content

Getting started

timbre is a React Native audio player built on libmpv, paired with a player-agnostic media session that keeps the lock screen, notification, Bluetooth controls and background playback alive after the app's UI is gone.

It ships as four packages with no cross-dependencies — pick the ones you need:

PackageWhat it does
@afkcodes/timbre-playerThe libmpv audio player: loading, queue, gapless, EQ, chapters, visualizer, hooks.
@afkcodes/timbre-audio-sessionAudio focus, interruptions, the "becoming noisy" route change — the OS arbitration layer.
@afkcodes/timbre-media-sessionThe lock screen / notification / Android Auto / CarPlay session. Works with any player.
@afkcodes/timbre-castChromecast sender: discovery, session handoff, receiver-side queue.
Pre-release

The packages are consumed from this workspace today — nothing is on npm yet, and the scope below is a placeholder until the name is chosen. APIs may still change.

Install

npm install @afkcodes/timbre-player @afkcodes/timbre-audio-session @afkcodes/timbre-media-session react-native-nitro-modules

On iOS, add the background audio mode and run pod install; Android needs no setup. The install is one Nitro peer dependency and the pinned libmpv binaries.

Where to next

  • The music-player guide — a complete, runnable app: queue, gapless, lock screen, shuffle/repeat, and a session that survives process death. Every sample on it typechecks against the real source.
  • Position anchors — why position is never streamed across the bridge, and how every surface projects it locally.
  • API reference — the full, generated @afkcodes/timbre-player surface: every export, its signature, and its contract.

The two gates

Everything on this site is held to two hard rules, both enforced in CI:

  1. Every code sample typechecks against the packages' source — a sample that drifts from the API is a build failure, not a stale snippet.
  2. Every public export is documented — the API reference is generated from each package's real index.ts, and a coverage check fails on anything missing.

See the repository for the full source and the roadmap.