Build audio plugins in Rust. One codebase, every format.
Write your plugin once. Build CLAP, VST3, VST2, AU v2, AU v3, AAX, LV2, and standalone from a single Rust codebase. Hot-reload DSP and GUI changes without restarting the DAW.
# Install the CLI (one-time)
cargo install --git https://github.com/truce-audio/truce cargo-truce
# Scaffold a new plugin
cargo truce new my-plugin
cd my-plugin
# Build and install (CLAP by default)
cargo truce install --clap
# Open your DAW, scan for plugins, load "MyPlugin"Other formats:
cargo truce install # formats in your plugin's default features
cargo truce install --vst3 # VST3
cargo truce install --vst2 # VST2 (opt-in, legacy — see note below)
cargo truce install --lv2 # LV2
cargo truce install --au3 # AU v3 (macOS, requires Xcode)
cargo truce install --aax # AAX (requires AAX SDK)
cargo truce test # run tests
cargo truce validate # auval + pluginval + clap-validatorShip it — produce a signed distributable installer:
cargo truce package # signed .pkg (macOS) or Inno Setup .exe (Windows)
# → dist/<Plugin>-<version>-<platform>.{pkg,exe}
cargo truce package -p my-plugin --formats clap,vst3,aax # subset
cargo truce package --no-sign # dev builds, skip signingOn macOS this runs pkgbuild + productbuild with Developer ID signing
and optional notarization. On Windows it stages each format,
Authenticode-signs via signtool, PACE-signs AAX via wraptool, and
compiles an Inno Setup installer via ISCC.exe. Credentials (Developer
ID / Azure Trusted Signing / cert thumbprint / .pfx) are configured
per-platform in truce.toml.
Scaffolded plugins default to CLAP + VST3. VST2, AU, and AAX are
opt-in per plugin via Cargo.toml features. On Windows, cargo truce install must be run from an Administrator command prompt (plugin
directories are system-wide).
use truce::prelude::*;
#[derive(Params)]
pub struct GainParams {
#[param(name = "Gain", range = "linear(-60, 6)",
unit = "dB", smooth = "exp(5)")]
pub gain: FloatParam,
}
pub struct Gain { params: Arc<GainParams> }
impl Gain {
pub fn new(params: Arc<GainParams>) -> Self { Self { params } }
}
impl PluginLogic for Gain {
fn reset(&mut self, sr: f64, _bs: usize) {
self.params.set_sample_rate(sr);
}
fn process(&mut self, buffer: &mut AudioBuffer, _events: &EventList,
_ctx: &mut ProcessContext) -> ProcessStatus {
for i in 0..buffer.num_samples() {
let gain = db_to_linear(self.params.gain.smoothed_next() as f64) as f32;
for ch in 0..buffer.channels() {
let (inp, out) = buffer.io(ch);
out[i] = inp[i] * gain;
}
}
ProcessStatus::Normal
}
fn layout(&self) -> GridLayout {
GridLayout::build("GAIN", "V0.1", 2, 50.0, vec![widgets(vec![
knob(0, "Gain"),
])])
}
}
truce::plugin! { logic: Gain, params: GainParams }That's a complete plugin with smoothed params, a GPU-rendered GUI knob, and CLAP + VST3 + AU exports.
By platform:
| Format | macOS | Windows | Linux |
|---|---|---|---|
| CLAP | Yes | Yes | Yes |
| VST3 | Yes | Yes | Yes |
| VST2 | Yes | Yes | Yes |
| LV2 | Yes | Yes | Yes |
| AU v2 | Yes | — | — |
| AU v3 | Yes | — | — |
| AAX | Yes | Yes | — |
AU is macOS-only by design. LV2 is the native Linux format and also builds on macOS and Windows — supports audio, MIDI, state, and UI (X11UI on Linux, CocoaUI on macOS, WindowsUI on Windows). AAX requires the Avid AAX SDK and PACE/iLok signing for retail Pro Tools releases. VST2 is opt-in on all platforms — see note below. See Status for host coverage.
By host (across all supported platforms):
| Format | Reaper | Logic | GarageBand | Ableton | FL Studio | Pro Tools |
|---|---|---|---|---|---|---|
| CLAP | Yes | |||||
| VST3 | Yes | Yes | Yes | |||
| VST2 | Yes | Yes | Yes | |||
| LV2 | Yes | |||||
| AU v2 | Yes | Yes | Yes | Yes | ||
| AU v3 | Yes | Yes | Yes | |||
| AAX | Yes |
| Plugin | Type | GUI | Screenshot |
|---|---|---|---|
| gain | Effect | Built-in | ![]() |
| eq | Effect | Built-in | ![]() |
| synth | Instrument | Built-in | ![]() |
| transpose | MIDI | Built-in | ![]() |
| arpeggio | MIDI | Built-in | ![]() |
| gain-egui | Effect | egui | ![]() |
| gain-iced | Effect | Iced | ![]() |
| gain-slint | Effect | Slint | ![]() |
- 7 plugin formats from one codebase (CLAP, VST3 default; VST2, LV2, AU v2, AU v3, AAX opt-in)
- Cross-platform — macOS, Windows, and Linux
- Hot reload — edit DSP/layout, rebuild, hear changes without restarting the DAW
- Flexible GUI frameworks — Built-in widgets, egui, iced, slint, or raw window handle
- Declarative params —
#[derive(Params)]+#[param(...)]with smoothing, ranges, units truce::plugin!— one macro generates all format exports + GUI + state serializationcargo truce— build, bundle, sign, install, validate, cleancargo truce package— signed distributable installers on both platforms (.pkgwith notarization on macOS; Inno Setup.exewith Authenticode on Windows)- Zero-copy audio — format wrappers pass host buffers directly
- Thread-safe params — atomic storage, lock-free access from any thread
- Automated tests — render, state, params, GUI screenshots, binary validation
- Automated validation —
cargo truce validateruns auval, pluginval, and clap-validator in one command
crates/
├── truce # Facade (re-exports, plugin! macro)
├── truce-core # Plugin, AudioBuffer, events, state
├── truce-params # FloatParam, BoolParam, EnumParam, smoothing
├── truce-params-derive # #[derive(Params)] proc macro
├── truce-build # build.rs helper (reads truce.toml)
├── truce-clap # CLAP format wrapper
├── truce-vst3 # VST3 format wrapper
├── truce-vst2 # VST2 format wrapper (clean-room)
├── truce-lv2 # LV2 format wrapper
├── truce-aax # AAX format wrapper
├── truce-au # Audio Unit (v2 + v3)
├── truce-standalone # Standalone host (cpal audio)
├── truce-gui # Built-in GUI (wgpu GPU rendering, 6 widgets)
├── truce-gpu # wgpu backend for built-in GUI
├── truce-egui # egui GUI integration
├── truce-iced # Iced GUI integration
├── truce-slint # Slint GUI integration
├── truce-loader # Hot-reload (native ABI, PluginLogic trait)
├── truce-xtask # Build/bundle/install library
├── truce-test # Test utilities + GUI snapshot tests
├── cargo-truce # Scaffolding CLI (cargo truce new)
- Quickstart — zero to hearing your plugin in 5 minutes
- Tutorials — parameters, processing, synth, GUI, hot reload
- Status — what's built, what's next
Plugin metadata lives in truce.toml:
[vendor]
name = "My Company"
id = "com.mycompany"
au_manufacturer = "MyCo"
[[plugin]]
name = "My Effect"
suffix = "effect"
crate = "my-effect"
category = "effect"
au_subtype = "MyFx"- Rust 1.75+ (
rustup update). Slint integration requires 1.88+. - macOS: Xcode CLI tools (
xcode-select --install). Full Xcode for AU v3. - Windows: MSVC build tools (Visual Studio 2019+ with the "Desktop
development with C++" workload). Rust
x86_64-pc-windows-msvctoolchain is required. - Linux: X11 + Vulkan development headers and JACK (via the PipeWire shim on modern distros).
- AAX: Avid AAX SDK (optional, obtain from developer.avid.com).
MIT OR Apache-2.0







