Skip to content

WorldLinkStudio/ableton-live-extensions

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ableton-live-extensions

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.


react-extension

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.

react-extension dialog

Prerequisites

  • Node.js ≥ 22.11.0
  • pnpm
  • Ableton Live 12 (with Extensions support enabled)

1. Copy the SDK tarballs to the repo root

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/.

2. Install dependencies

cd extensions/react-extension
pnpm install

3. Configure .env

Copy 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.node

This file is gitignored — each developer sets it for their own machine.


Running locally

Standard run (production build → extension host)

Builds the extension and launches it inside Live's extension host:

pnpm start

Live must already be running. The extension loads and its context-menu actions become available immediately.

Hot-reload run (dialog UI via Vite dev server)

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:dev

Terminal 2 — start the extension host pointed at the dev server:

pnpm start:hot

DIALOG_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.


Testing and debugging

Type-check

pnpm build:dev   # runs tsc --noEmit then builds with esbuild

Lint

pnpm lint        # Biome check
pnpm lint:fix    # Biome check --write (auto-fix)

Dialog UI in the browser

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.

Inspecting the WebView (macOS)

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.


Sending data to the extension host from the dialog

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 dialog

To pass data back with a meaningful payload, replace the "null" param with your serialized result before calling sendToHost.


How it works

  1. src/extension.ts registers a command (reactExt.helloWorld) and attaches it to the context menu of audio and MIDI tracks.
  2. When triggered, the command builds an InitialData object, serializes it into the generated dialog HTML via buildDialogUrl, and opens it as a modal.
  3. The React app (src/dialog/) reads InitialData through useLiveBridge and renders the UI.
  4. The dialog calls sendToHost (or close) to signal the extension host when it is done.

Building for distribution

pnpm build      # production build
pnpm package    # packages the extension for installation in Live

The packaged file can be installed in Ableton Live via Live → Extensions → Install Extension.


Project structure

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

About

Ableton Live Extensions

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors