Bluetooth devices (Linux only — wraps BlueZ via D-Bus).
Bluetooth devices (Linux only — wraps BlueZ via D-Bus).
Filesystem browser — walk the configured music_dir.
Filesystem browser — walk the configured `music_dir`.
Idiomatic Clojure SDK for Rockbox.
(require '[rockbox.core :as rb]
'[rockbox.playback :as pb]
'[rockbox.library :as lib])
(def client (rb/client))
;; Optional: open the WebSocket for real-time events
(rb/connect client)
(rb/on client :track-changed
(fn [t] (println "▶" (:title t) "—" (:artist t))))
;; Look at what's playing
(when-let [t (pb/current-track client)]
(println (:title t)))
;; Pipe-friendly: actions return the client so they compose
(-> client
(pb/pause)
(pb/seek 90000)
(pb/resume))
| Domain | Namespace |
|---|---|
| Transport controls | rockbox.playback |
| Library / search | rockbox.library |
| Live queue | rockbox.playlist |
| Saved playlists | rockbox.saved-playlists |
| Smart playlists | rockbox.smart-playlists |
| Volume | rockbox.sound |
| Settings | rockbox.settings |
| System info | rockbox.system |
| Filesystem browser | rockbox.browse |
| Output devices | rockbox.devices |
| Bluetooth (Linux) | rockbox.bluetooth |
| Real-time events | rockbox.events |
| Plugin system | rockbox.plugin |
| Enums and helpers | rockbox.types |
Idiomatic Clojure SDK for [Rockbox](https://www.rockbox.org).
## Quick start
(require '[rockbox.core :as rb]
'[rockbox.playback :as pb]
'[rockbox.library :as lib])
(def client (rb/client))
;; Optional: open the WebSocket for real-time events
(rb/connect client)
(rb/on client :track-changed
(fn [t] (println "▶" (:title t) "—" (:artist t))))
;; Look at what's playing
(when-let [t (pb/current-track client)]
(println (:title t)))
;; Pipe-friendly: actions return the client so they compose
(-> client
(pb/pause)
(pb/seek 90000)
(pb/resume))
## Module map
| Domain | Namespace |
|-----------------------|----------------------------|
| Transport controls | `rockbox.playback` |
| Library / search | `rockbox.library` |
| Live queue | `rockbox.playlist` |
| Saved playlists | `rockbox.saved-playlists` |
| Smart playlists | `rockbox.smart-playlists` |
| Volume | `rockbox.sound` |
| Settings | `rockbox.settings` |
| System info | `rockbox.system` |
| Filesystem browser | `rockbox.browse` |
| Output devices | `rockbox.devices` |
| Bluetooth (Linux) | `rockbox.bluetooth` |
| Real-time events | `rockbox.events` |
| Plugin system | `rockbox.plugin` |
| Enums and helpers | `rockbox.types` |Remote output sinks discovered via mDNS — Chromecast, AirPlay, etc.
Remote output sinks discovered via mDNS — Chromecast, AirPlay, etc.
Typed exceptions for the Rockbox SDK.
All errors are clojure.lang.ExceptionInfo instances carrying a :type
key in their ex-data, so they can be discriminated with ex-data /
(:type ...) in a single catch ExceptionInfo block.
(try
(rb/query client "...")
(catch clojure.lang.ExceptionInfo e
(case (:type (ex-data e))
:rockbox/network (handle-offline e)
:rockbox/graphql (handle-server-error e)
(throw e))))
Typed exceptions for the Rockbox SDK.
All errors are `clojure.lang.ExceptionInfo` instances carrying a `:type`
key in their ex-data, so they can be discriminated with `ex-data` /
`(:type ...)` in a single `catch ExceptionInfo` block.
(try
(rb/query client "...")
(catch clojure.lang.ExceptionInfo e
(case (:type (ex-data e))
:rockbox/network (handle-offline e)
:rockbox/graphql (handle-server-error e)
(throw e))))Event registry and dispatch.
Listeners are stored on the client itself (in an atom) so a single client value can be passed around and shared between threads safely.
(-> client
(rb/connect)
(events/on :track-changed (fn [t] (println "▶" (:title t))))
(events/on :status-changed (fn [s] (println "status:" s))))
(require '[clojure.core.async :as a])
(def ch (events/channel client :track-changed))
(a/go-loop []
(when-let [t (a/<! ch)]
(println (:title t))
(recur)))
Supported events: :track-changed :status-changed :playlist-changed :ws-open :ws-close :ws-error
Event registry and dispatch.
Listeners are stored on the client itself (in an atom) so a single client
value can be passed around and shared between threads safely.
## Pipe-friendly callback API
(-> client
(rb/connect)
(events/on :track-changed (fn [t] (println "▶" (:title t))))
(events/on :status-changed (fn [s] (println "status:" s))))
## core.async channel API
(require '[clojure.core.async :as a])
(def ch (events/channel client :track-changed))
(a/go-loop []
(when-let [t (a/<! ch)]
(println (:title t))
(recur)))
Supported events: `:track-changed :status-changed :playlist-changed
:ws-open :ws-close :ws-error`Library queries (albums, artists, tracks, search) and likes.
Library queries (albums, artists, tracks, search) and likes.
Transport controls and one-call play helpers.
(-> client
(pb/play-album "album-id" {:shuffle true})
(pb/seek 90000))
Action functions return the client so they compose with ->. Read
functions return data.
Transport controls and one-call play helpers.
(-> client
(pb/play-album "album-id" {:shuffle true})
(pb/seek 90000))
Action functions return the client so they compose with `->`. Read
functions return data.Live playback queue management — what's currently playing and what's
queued up next. For persistent named playlists see rockbox.saved-playlists.
Live playback queue management — what's currently playing and what's queued up next. For persistent named playlists see `rockbox.saved-playlists`.
Plugin system inspired by Jellyfin's IPlugin and Mopidy's frontend
extensions. A plugin is a plain map with at minimum a :name and
:install function:
(def my-scrobbler
{:name "lastfm-scrobbler"
:version "1.0.0"
:description "Scrobble plays to Last.fm"
:install (fn [{:keys [client query events]}]
(events/on client :track-changed
(fn [t] (submit-scrobble t))))
:uninstall (fn [] (disconnect-lastfm))})
Install with rockbox.core/use-plugin. The :install fn receives a
context map: {:client client :query query-fn :events events-ns}.
Plugin system inspired by Jellyfin's IPlugin and Mopidy's frontend
extensions. A plugin is a plain map with at minimum a `:name` and
`:install` function:
(def my-scrobbler
{:name "lastfm-scrobbler"
:version "1.0.0"
:description "Scrobble plays to Last.fm"
:install (fn [{:keys [client query events]}]
(events/on client :track-changed
(fn [t] (submit-scrobble t))))
:uninstall (fn [] (disconnect-lastfm))})
Install with `rockbox.core/use-plugin`. The `:install` fn receives a
context map: `{:client client :query query-fn :events events-ns}`.Persistent named playlists stored in the database, with folder support.
Persistent named playlists stored in the database, with folder support.
Read and write global rockboxd settings (volume, EQ, repeat mode, ...).
Read and write global rockboxd settings (volume, EQ, repeat mode, ...).
Smart (rule-based) playlists and listening stats.
Smart (rule-based) playlists and listening stats.
Volume control. Values are in firmware-defined steps, not absolute dB.
Volume control. Values are in firmware-defined steps, not absolute dB.
System info — daemon version and global runtime status.
System info — daemon version and global runtime status.
HTTP transport for GraphQL queries — built on java.net.http.HttpClient
so the SDK has no third-party HTTP dependency.
You normally don't call this directly; use rockbox.core/query or one of
the domain APIs (rockbox.playback, rockbox.library, ...). Exposed for
plugin authors and advanced consumers who need a stable hook.
HTTP transport for GraphQL queries — built on `java.net.http.HttpClient` so the SDK has no third-party HTTP dependency. You normally don't call this directly; use `rockbox.core/query` or one of the domain APIs (`rockbox.playback`, `rockbox.library`, ...). Exposed for plugin authors and advanced consumers who need a stable hook.
Enum constants and tiny helpers for Rockbox values that come back as ints or attribute bitmasks.
Constants are exposed both as namespaced keywords (idiomatic in Clojure) and as the raw integers the firmware uses. Use whichever fits your code:
(require '[rockbox.types :as t])
(= (:status track) (t/playback-status :playing)) ; via keyword
(= (:status track) t/playing) ; via raw int alias
Enum constants and tiny helpers for Rockbox values that come back as ints
or attribute bitmasks.
Constants are exposed both as namespaced keywords (idiomatic in Clojure)
and as the raw integers the firmware uses. Use whichever fits your code:
(require '[rockbox.types :as t])
(= (:status track) (t/playback-status :playing)) ; via keyword
(= (:status track) t/playing) ; via raw int aliasInternal helpers — case conversion between Clojure (kebab-case keywords) and GraphQL (camelCase strings).
Internal helpers — case conversion between Clojure (kebab-case keywords) and GraphQL (camelCase strings).
WebSocket transport implementing the graphql-ws subprotocol
(https://github.com/enisdenjo/graphql-ws/blob/master/PROTOCOL.md).
Uses java.net.http.WebSocket so there is no third-party WS dependency.
Auto-reconnects with exponential backoff up to 30 s. Fires :ws-open,
:ws-close, :ws-error events through the SDK's event registry.
This is an internal namespace — call rockbox.core/connect instead.
WebSocket transport implementing the `graphql-ws` subprotocol (https://github.com/enisdenjo/graphql-ws/blob/master/PROTOCOL.md). Uses `java.net.http.WebSocket` so there is no third-party WS dependency. Auto-reconnects with exponential backoff up to 30 s. Fires `:ws-open`, `:ws-close`, `:ws-error` events through the SDK's event registry. This is an internal namespace — call `rockbox.core/connect` instead.
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |