Build audio plugins in Rust.

CLAP, VST3, LV2, AU v2, AU v3, AAX, and standalone — from a single Rust crate. Install and load your plugin in a DAW in five minutes.

# Install the CLI (one-time)
cargo install cargo-truce

# Scaffold a new plugin
cargo truce new my-plugin
cd my-plugin

# Run the plugin standalone — no DAW needed
cargo truce run

# Build and install
cargo truce install --clap
cargo truce install --vst3

# Open your DAW, scan for plugins, load "MyPlugin"

Overview

Capabilities

One Rust codebase compiles to seven plugin formats. Hot reload, declarative params, cross-platform installers, automated validation.

7 plugin formats

CLAP and VST3 by default; VST2, LV2, AU v2, AU v3, and AAX are opt-in per crate. One Rust codebase, every host.

Hot reload

Edit DSP or layout, rebuild, hear changes without restarting your DAW.

Declarative params

#[derive(Params)] with ranges, units, and smoothing. Atomic storage, lock-free access from any thread.

Pick your GUI

Built-in widgets, egui, iced, Slint, or raw window handle. The same plugin, your choice of toolkit.

Cross-platform

macOS, Windows, and Linux. The CLI handles signing, notarization, installers, and validation.

Validation built in

cargo truce validate runs auval, pluginval, and clap-validator in one command on installed plugins.

Compatibility

Format support

CLAP and VST3 ship as defaults. VST2, LV2, AU, and AAX are opt-in per plugin via Cargo features.

FormatmacOSWindowsLinux
CLAPYesYesYes
VST3YesYesYes
VST2YesYesYes
LV2YesYesYes
AU v2Yes
AU v3Yes
AAXYesYes

Example

A complete plugin

Smoothed parameter, GPU-rendered knob, CLAP + VST3 + standalone. The truce::plugin! macro generates every format export, GUI, and state serialization.

use truce::prelude::*;
use truce_gui_types::layout::{knob, widgets, GridLayout};

#[derive(Params)]
pub struct GainParams {
    #[param(name = "Gain", range = "linear(-60, 6)",
            unit = "dB", smooth = "exp(5)")]
    pub gain: FloatParam,
}

use GainParamsParamId as P;

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.read());
            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(vec![widgets(vec![knob(P::Gain, "Gain")])])
    }
}

truce::plugin! { logic: Gain, params: GainParams }

Plugins

Built with truce

Open-source plugins built on the framework.