Extensions for Ableton® Live built with the Ableton Extensions SDK.
Ableton is a registered trademark of Ableton AG. This project is not affiliated with or endorsed by Ableton AG.
A sample Ableton Live extension that renders a React + Tailwind dialog inside Live's built-in WebView. It registers a context-menu action on audio and MIDI tracks that opens a modal showing data passed from the extension host.
- Node.js ≥ 22.11.0
- pnpm
- Ableton Live 12 (with Extensions support enabled)
The SDK and CLI are distributed as local tarballs. Both files must be present at the repo root before installing dependencies:
ableton-extensions-sdk-1.0.0-beta.0.tgz
ableton-extensions-cli-1.0.0-beta.0.tgz
package.json references them via file:../../<tarball>, so the paths must resolve from extensions/react-extension/.
cd extensions/react-extension
pnpm installCopy the example and set the path to Live's ExtensionHost native module on your machine:
cp .env.example .env # if an example exists, otherwise edit .env directly.env:
# Path to Ableton Live's ExtensionHost native module on this machine.
# Adjust the app name/path to match your Live installation.
EXTENSION_HOST_PATH=/Applications/Ableton Live 12.app/Contents/Helpers/ExtensionHost/ExtensionHostNodeModule.nodeThis file is gitignored — each developer sets it for their own machine.
Builds the extension and launches it inside Live's extension host:
pnpm startLive must already be running. The extension loads and its context-menu actions become available immediately.
Opens two processes: the Vite dev server for the React dialog UI and the extension host for the extension logic. Changes to the dialog reload instantly without rebuilding.
Terminal 1 — start the Vite dev server:
pnpm dialog:devTerminal 2 — start the extension host pointed at the dev server:
pnpm start:hotDIALOG_DEV_SERVER=http://localhost:5173 is set automatically by the start:hot script. When this env var is present, buildDialogUrl passes InitialData as a ?data= query param instead of injecting it into the HTML, so the Vite app can read it during development.
pnpm build:dev # runs tsc --noEmit then builds with esbuildpnpm lint # Biome check
pnpm lint:fix # Biome check --write (auto-fix)Because pnpm dialog:dev serves the React app on http://localhost:5173, you can open it in any browser for rapid UI iteration. Pass mock data via the query string:
http://localhost:5173?data=%7B%22greeting%22%3A%22Hello%20from%20browser%22%7D
The useLiveBridge hook reads ?data= first, then falls back to window.__INITIAL_DATA__ (injected by the extension host in production), so the app works identically in both environments.
When the extension host is running, open Safari → Develop → [your machine] → Extension WebView to attach Safari DevTools to the dialog WebView and inspect the DOM, console, and network.
Use the sendToHost helper (defined in src/dialog/hooks/useLiveBridge.ts) to post messages back to the extension host. It targets the correct native bridge automatically — webkit.messageHandlers.live on macOS, chrome.webview on Windows:
function sendToHost(message: Record<string, unknown>): void {
const wk = window.webkit?.messageHandlers?.live;
const wv = window.chrome?.webview;
if (wk) {
wk.postMessage(message);
} else if (wv) {
wv.postMessage(message);
}
}Call it from any component or hook:
// Close the dialog and return a value to the extension host
sendToHost({ method: "close_and_send", params: ["null"] });
// Send arbitrary data
sendToHost({ method: "my_method", params: [{ foo: "bar" }] });The useLiveBridge hook exposes a close helper that calls close_and_send for you:
const { data, close } = useLiveBridge();
// data — InitialData passed in from extension.ts
// close — sends close_and_send to the host and dismisses the dialogTo pass data back with a meaningful payload, replace the "null" param with your serialized result before calling sendToHost.
src/extension.tsregisters a command (reactExt.helloWorld) and attaches it to the context menu of audio and MIDI tracks.- When triggered, the command builds an
InitialDataobject, serializes it into the generated dialog HTML viabuildDialogUrl, and opens it as a modal. - The React app (
src/dialog/) readsInitialDatathroughuseLiveBridgeand renders the UI. - The dialog calls
sendToHost(orclose) to signal the extension host when it is done.
pnpm build # production build
pnpm package # packages the extension for installation in LiveThe packaged file can be installed in Ableton Live via Live → Extensions → Install Extension.
extensions/react-extension/
├── src/
│ ├── extension.ts # Extension entry point (runs in Node.js)
│ ├── messages.ts # Shared types between host and dialog
│ ├── utils/
│ │ └── buildDialogUrl.ts # Serializes InitialData into the dialog URL
│ └── dialog/ # React app (runs in Live's WebView)
│ ├── App.tsx
│ ├── main.tsx
│ ├── hooks/
│ │ └── useLiveBridge.ts # Reads InitialData; exposes sendToHost / close
│ └── bridge.d.ts # Global types for webkit / chrome WebView bridges
├── manifest.json # Extension metadata
├── .env # Local env (gitignored)
├── build.ts # esbuild script for the extension bundle
└── vite.config.ts # Vite config for the dialog UI
