Quick start
# One-time install
cargo install cargo-truce
# Scaffold a plugin
cargo truce new my-plugin
cd my-plugin
# Run standalone — no DAW needed
cargo truce run
# Build and install for your DAW
cargo truce install --clap
cargo truce install --vst3
Open your DAW, scan for plugins, load MyPlugin. For a chapter-by-chapter walkthrough, follow the Guide from install through hot reload. For look-up material — every CLI flag, every #[param(...)] key, every truce.toml field — jump to the Reference. For working code to read top-to-bottom, browse the Examples.
Build profile. Every
cargo trucecommand (install,build,package,run,screenshot) defaults to the cargo release profile — plugins are typically loaded into a DAW where debug-build DSP can spike CPU under load. Pass--debugto opt into the cargo dev profile for fast-compile iteration.
#Guide
A walkthrough of building, iterating on, and shipping a truce plugin. Read top-to-bottom on first pass; return to specific chapters as needed.
| # | Chapter | What you get |
|---|---|---|
| 1 | install | Rust + the platform compiler + cargo install cargo-truce + cargo truce doctor. CLAP+VST3 minimum-friction setup; AU/AAX/packaging deferred. |
| 2 | first-plugin | cargo truce new, a tour of the generated files, install, load in a DAW. |
| 3 | plugin-anatomy | PluginLogic trait, bus layouts, state persistence. |
| 4 | parameters | #[derive(Params)], smoothing patterns, meters. Attribute reference in reference/params. |
| 5 | processing | process() patterns for effects, MIDI, sample-accurate events, synths. Includes the truce_simd per-block ops + math helpers for hot paths. |
| 6 | fundsp | Drop a fundsp graph into process() — combinator DSL, Shared cells for sample-accurate automation, RT60 rebuild patterns. |
| 7 | midi | Reading and emitting MIDI events; per-format support; testing MIDI plugins. |
| 8 | gui | Built-in GUI widgets + the alternative backends (egui, iced, Slint, Vizia, raw window handle). |
| 9 | audio-testing | truce_test::PluginDriver for in-process audio + MIDI regression tests — no DAW required. |
| 10 | presets | Factory presets in every format from .preset TOML; in-DAW authoring via cargo truce preset pull; cross-format conversion; preset packs. |
| 11 | shipping | cargo truce install / build / validate / package, signing, installers. |
| 12 | ios | iOS-specific workflow: simulator iteration, device + .ipa signing, per-plugin truce.toml knobs, preview-audio mute, screenshot regression. |
| 13 | hot-reload | ~2 second edit → hear loop with --shell. Experimental — dev-loop only. |
#GUI backends
Pick a toolkit. The built-in widget set covers most plugin UIs; the alternatives are there when you need something the built-in widgets don't ship.
- Built-in widgets —
GridLayoutbuilder, every widget constructor, theming - egui · iced · Slint · Vizia · Raw window handle
- Screenshot testing — visual regression tests for the GUI
#Reference
Not exhaustive — for the full Rust API surface, see the rustdoc.
| Page | What's in it |
|---|---|
| cli | Every cargo truce subcommand and flag — new, install, build, validate, package, run, doctor, uninstall, screenshot. |
| params | #[derive(Params)] and #[param(...)] — every attribute key, range syntax, smoothing modes, meters, custom formatting. |
| truce-toml | Project-level truce.toml schema: [vendor], [[plugin]], [[suite]], packaging. Signing identities and other secrets live in env — see cargo-config. |
| cargo-config | Per-developer .cargo/config.toml [env] table — every environment variable truce reads (signing identities, SDK paths, validator paths, hot-reload). |
#Examples
Short, one-file plugin examples that double as canonical references for parameter shapes, processing patterns, GUI layouts, and MIDI. Full list with screenshots: examples.
| Plugin | Type | GUI | What it shows |
|---|---|---|---|
| gain | Effect | Built-in | Minimal plugin: one FloatParam, a single-channel multiply. |
| eq | Effect | Built-in | Multi-band biquad EQ with smoothed coefficients. |
| synth | Instrument | Built-in | MIDI-driven polyphonic synth with per-voice envelopes. |
| transpose | MIDI | Built-in | MIDI effect — rewrite note numbers in process(). |
| arpeggio | MIDI | Built-in | Sample-accurate MIDI scheduling against the host transport. |
| tremolo | Effect | egui | Tempo-synced LFO + the egui backend wired in. |
| state | Effect | egui | Custom #[derive(State)] for persistent extra state. |
| fundsp-reverb-simple | Effect | Built-in | Stereo plate reverb on a fundsp graph (pedagogical, inline rebuild). |
| fundsp-reverb-worker | Effect | Built-in | Same reverb with a background-thread graph rebuild + lock-free swap — process() stays alloc-free. |
| gain-egui | Effect | egui | Same plugin as gain, rendered with egui. |
| gain-iced | Effect | Iced | Same plugin, rendered with Iced. |
| gain-slint | Effect | Slint | Same plugin, rendered with Slint. |
| gain-vizia | Effect | Vizia | Same plugin, rendered with Vizia. |
The five gain* variants implement the same plugin against
different GUI frameworks — compare them side-by-side to pick a
toolkit. The two fundsp-reverb-* crates share a topology and
signal flow but differ only in how the fundsp graph gets
rebuilt; chapter 6 → fundsp walks through both.
#Formats
Truce compiles a single plugin crate into up to seven plugin formats, plus an app-mode standalone binary. Scaffolded plugins enable clap, vst3, and standalone by default; everything else is opt-in.
| Format | Cargo feature | macOS | Windows | Linux | Scaffolded default | Extras required |
|---|---|---|---|---|---|---|
| CLAP | clap |
✅ | ✅ | ✅ | ✅ | — |
| VST3 | vst3 |
✅ | ✅ | ✅ | ✅ | — |
| VST2 | vst2 |
✅ | ✅ | ✅ | opt-in | read licensing note |
| LV2 | lv2 |
✅ | ✅ | ✅ | opt-in | — |
| AU v2 | au |
✅ | — | — | opt-in | Xcode CLI tools |
| AU v3 | au |
✅ | — | — | opt-in | full Xcode, Developer ID signing |
| AU v3 (iOS) | au |
✅ (iOS) | — | — | opt-in | Xcode, Apple Developer team ID for device / .ipa |
| AAX | aax |
✅ | ✅ | — | opt-in | AAX SDK (+ PACE wraptool for retail) |
| Standalone | standalone |
✅ | ✅ | ✅ | ✅ | — (app mode, not a host-loaded format) |
Two ways to enable an opt-in format. Per install: cargo truce install --vst2 (one-off). Permanently: add it to [features].default in Cargo.toml.
#Install destinations
cargo truce install defaults to per-user paths on every platform — no sudo / Administrator prompt. Pass --system for the system-wide directories (sudo on macOS, Administrator shell on Windows). AAX, AU v3, and Windows VST2 are always system-only — --user for those falls back to the system path with a one-line note (†). Linux is user-scope only: --user and --system resolve to the same paths every Linux host already scans.
The bold cell in each row is the destination cargo truce install lands at by default (no flag). Other cells are reached by passing --system (or, for system-only formats, by passing --system explicitly so the † fallback note is suppressed).
| Format | macOS user | macOS system | Windows user | Windows system | Linux |
|---|---|---|---|---|---|
| CLAP | ~/Library/Audio/Plug-Ins/CLAP/{Name}.clap |
/Library/Audio/Plug-Ins/CLAP/{Name}.clap |
%LOCALAPPDATA%\Programs\Common\CLAP\{Name}.clap |
%COMMONPROGRAMFILES%\CLAP\{Name}.clap |
~/.clap/{Name}.clap |
| VST3 | ~/Library/Audio/Plug-Ins/VST3/{Name}.vst3/ |
/Library/Audio/Plug-Ins/VST3/{Name}.vst3/ |
%LOCALAPPDATA%\Programs\Common\VST3\{Name}.vst3\ |
%COMMONPROGRAMFILES%\VST3\{Name}.vst3\ |
~/.vst3/{Name}.vst3/ |
| VST2 | ~/Library/Audio/Plug-Ins/VST/{Name}.vst/ |
/Library/Audio/Plug-Ins/VST/{Name}.vst/ |
system† | %PROGRAMFILES%\Steinberg\VstPlugins\{Name}.dll |
~/.vst/{Name}.so |
| LV2 | ~/Library/Audio/Plug-Ins/LV2/{Name}.lv2/ |
/Library/Audio/Plug-Ins/LV2/{Name}.lv2/ |
%APPDATA%\LV2\{Name}.lv2\ |
%COMMONPROGRAMFILES%\LV2\{Name}.lv2\ |
~/.lv2/{Name}.lv2/ |
| AU v2 | ~/Library/Audio/Plug-Ins/Components/{Name}.component/ |
/Library/Audio/Plug-Ins/Components/{Name}.component/ |
— | — | — |
| AU v3 | system† | /Applications/{Name}.app/Contents/PlugIns/AUExt.appex/ |
— | — | — |
| AAX | system† | /Library/Application Support/Avid/Audio/Plug-Ins/{Name}.aaxplugin/ |
system† | %COMMONPROGRAMFILES%\Avid\Audio\Plug-Ins\{Name}.aaxplugin\ |
— |
| Standalone | target/bundles/{Name}.standalone/ (staged by cargo truce run; not installed) |
same | same | same | same |
cargo truce install is the supported way to land bundles in these dirs; the paths are listed here as a debug aid when plugins aren't being picked up. cargo truce doctor prints both scopes side-by-side with a writable / sudo / not-present marker. End-to-end packaging and --ask / --user / --system installer scope live in guide/shipping.