Skip to content
LEX
Keyboard: press / or Command K to ask or jump, backtick to open the terminal.

LEX · the pass

Order ticket

Ticket

#

From
Time
Order

Fire it

EN · DE · ES

Back to the Lab

Tools04 / 12

LaunchDeck

A Novation Launchpad as a programmable control surface

Status
Working, not deployed
Period
2026 →
Role
Design and development, end to end
For
Developers and power users who want physical controls for their desktop and their AI agents.

Problem

A grid of RGB pads is a great physical interface, but outside music software it does nothing. Meanwhile coding agents keep stopping to ask for permission, and every answer means switching windows.

A desktop app in Rust and Tauri that turns a Novation Launchpad into a control surface for the computer: pads open apps, press shortcuts, call services and light up to show state. AI agents can sit on the pads, so a permission request is approved or rejected with one press.

Case study

LaunchDeck is built around one rule: Rust owns the runtime, React only edits, visualises and configures. Closing the window does not stop the pads; the app keeps running from the tray.

A workspace holds surfaces, pages and pads. Each pad is assigned an action and a list of feedback rules that read live state or react to events, so the light always says something true. The Auto Context engine switches pages by the application in front. A simulated Launchpad X is built in, so everything works without hardware.

Agent Control puts AI agents on the grid. Claude Code connects through its hooks, other agents through a versioned WebSocket bridge on localhost. Registering never grants control, and a request is never approved by default: timeouts, errors and restarts all end in no decision.

It is the first project in a stack outside my usual web work: Rust, Tauri, MIDI and SysEx, and a WebAssembly plugin sandbox. Version 0.3.0 is the first external alpha.

Architecture

A Tauri 2 app: the Rust core runs devices, state, events, actions, plugins and agents on Tokio, and a React 19 editor talks to it through Tauri commands and events, with every payload validated by Zod on one side and by Rust on the other. MIDI goes through midir behind a backend trait, so tests use an in-memory fake. One device model serves the Launchpad X and the Mini MK3 from data profiles: it identifies the unit with a SysEx device inquiry, switches it to Programmer Mode, sends only the LEDs that changed and hands the device back as it found it. Plugins run in Wasmtime with fuel, time and memory limits, and reach the network only through a host broker restricted to origins the user granted.

Engineering decisions

  1. Rust owns the runtime and the UI only configures it, so the pads keep working with the window closed.
  2. A built-in simulated Launchpad written from Novation's manuals, independent of the codec, so the protocol is cross-checked without hardware.
  3. Plugins in a Wasmtime sandbox with no direct sockets: network access goes through a broker that checks every resolved address against what the user granted.
  4. Agent approvals fail closed: registering never grants control, and no request is ever approved by default.
  5. Architecture rules enforced by scripts and tests, including one that fails if the agent domain names a vendor.

Challenges & trade-offs

Building against hardware that was never attached: the MIDI protocol was implemented and byte-tested from Novation's manuals, and the physical Launchpad X and Mini MK3 are still to be verified. The other challenge was letting third-party plugins and agents act on the machine without trusting them.

Verified results

  • v0.3.0, the first external alpha
  • 1,299 Rust tests and 594 TypeScript tests passing on macOS
  • Claude Code hooks verified live; captured payloads used as test fixtures
  • 313 commits, MIT licence
  • Not yet verified on physical hardware; Windows and Linux not built for 0.3.0

Status labels are factual: nothing here is presented as more finished than it is.

Stack

Links

Ask or jump

Type a question or a name. Navigation is deterministic — no chatbot.

Press / or ⌘K