Files
nih-plug-template/README.md
T
mikkeli 3acab7bf7e feat: check descriptions and Rust type names for branding drift
The checker covered the identity strings a host sees, but not two other
kinds of template residue.

Descriptions: `Cargo.toml`'s `description` and `CLAP_DESCRIPTION` both
shipped as placeholders, and the latter surfaces in some host browsers.

Type names: `MyPlugin` and `PluginParams` appear at nine sites between
the struct definitions, the three trait impls, the two export macros and
the params field. Missing one is a compile error rather than silent drift,
so this is a convenience rather than a safety net - but naming the site
beats reading rustc, and the `Vst3Plugin` impl sits behind a cfg, so a
default build never reports it at all. Renaming the types is optional:
leave the canonical values alone and the checks stay green.

TODO markers are reported at a new informational level that never counts
toward pass/fail. They are legitimate while building, so failing on them
would just train you to ignore the run - but a finished plugin should not
quietly ship with five of them.

Two bugs surfaced while testing this:

- The stale scan drew its file list from `git ls-files`, which returns
  nothing outside a checkout. In an exported tarball every stale spelling
  was therefore reported absent - the section passed hardest exactly when
  it could see least. It now falls back to `find` and says which source
  it used.
- `grep -c` prints 0 and exits 1 when there are no matches, so the TODO
  count's `|| echo 0` appended a second zero and produced an unparseable
  value once a rename removed the last TODO.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WHt4DykxXaQnyaJfyS8KCn
2026-08-29 10:29:06 +09:00

5.0 KiB

NIH-plug Template

Minimal scaffold for new NIH-plug audio plugins (Rust + CLAP/VST3 + egui).

Based on patterns from musiikki/codename-206.

Quick Start

# Clone this repo as your starting point
git clone http://192.168.2.199:3005/musiikki/nih-plug-template my-plugin
cd my-plugin

# Edit: src/lib.rs, Cargo.toml, bundler.toml — replace placeholder values
# See musiikki/codename-206 for a real-world example of how to fill these in

# Then verify the rename landed everywhere
sh check-branding.sh

Renaming

Branding is duplicated across Cargo.toml, bundler.toml, src/lib.rs and the docs, and nothing makes those agree — so a half-finished rename builds a bundle under one name while the docs and deploy script look for another.

check-branding.sh declares the identity once at the top and asserts every copy matches:

sh check-branding.sh      # exit 0 = consistent, 1 = drift found

It covers the identity a host actually sees (package and bundle names, Plugin::NAME, VENDOR, EMAIL, CLAP_ID, VST3_CLASS_ID, the descriptions) and the Rust type names (MyPlugin, PluginParams) at every site they appear. Renaming the types is cosmetic — no host ever sees them — but leaving MyPlugin in a shipped plugin is the kind of residue that says nobody read the file. Leave them as-is and those checks simply stay green.

To rename: edit the canonical block at the top of the script, run it, and fix everything it reports. The placeholder spellings are pre-seeded into its STALE list, and each one arms itself as soon as you change the matching canonical value — so leftovers surface without you having to track them. It also asserts VST3_CLASS_ID is exactly 16 bytes and that CLAP_ID is reverse-DNS safe, both of which are otherwise a compile error or a silent identity change between machines.

Checks for files the template doesn't ship (e.g. a deploy.ps1) report as skip and start enforcing once you add them.

Build

# Install Rust via rustup: https://rustup.rs
# No VST3 SDK needed — NIH-plug bundles its own bindings.

# Build + bundle the CLAP (default)
cargo xtask bundle nih_plug_template --release

# Add the VST3 as well — see the licensing note below before you do this
cargo xtask bundle nih_plug_template --release --features vst3

Output: target/bundled/<name>.clap (and <name>.vst3 with --features vst3), where <name> is the name set in bundler.toml — not the crate name. Out of the box that means target/bundled/Plugin Name.clap.

On Linux the egui editor needs the GUI development headers:

sudo apt install pkg-config libgl-dev libx11-dev libxcursor-dev libxcb1-dev \
    libxcb-icccm4-dev libxcb-dri2-0-dev libx11-xcb-dev libxkbcommon-dev libxkbcommon-x11-dev

Deploy

FL Studio

Build with --features vst3 first if you want the VST3 (see the licensing note below).

FL Studio scans C:\Program Files\Common Files\VST3 by default, ignores directory junctions (so a symlinked bundle is invisible to its scanner), and caches failed scans.

  1. Copy the .vst3 bundle to a folder FL scans (e.g. C:\Program Files\Common Files\VST3).
  2. Copy the .clap bundle to a folder FL scans (e.g. C:\Program Files\Common Files\CLAP).
  3. In FL Studio: Options → Manage plugins → tick "Rescan previously failed plugins" → Find installed plugins, then search for your plugin name (set in bundler.toml).

Linux

# CLAP
cp -r "target/bundled/Plugin Name.clap" ~/.clap/

# VST3 (only exists if you built with --features vst3)
cp -r "target/bundled/Plugin Name.vst3" ~/.vst3/

# Or globally:
# sudo cp -r "target/bundled/Plugin Name.clap" /usr/lib/clap/
# sudo cp -r "target/bundled/Plugin Name.vst3" /usr/lib/vst3/

Project Structure

Cargo.toml          # Package deps + the opt-in `vst3` feature — NIH-plug pinned to codename-206's rev
bundler.toml        # Bundle name for `cargo xtask bundle`
src/lib.rs          # Plugin skeleton — params, DSP, and egui editor, with one example gain param
xtask/              # Bundler xtask (cargo xtask bundle)
.cargo/config.toml  # xtask alias
check-branding.sh   # Asserts the plugin's identity strings agree everywhere (see Renaming)
.gitattributes      # Pins *.sh to LF so Windows checkouts keep a valid shebang

License

Apache-2.0

VST3 Licensing Note

NIH-plug's VST3 bindings (vst3-sys) are GPLv3. Linking them makes the resulting binary GPLv3 regardless of what Cargo.toml declares, so VST3 is behind an opt-in vst3 feature and this template builds CLAP only by default. That keeps the default build consistent with the Apache-2.0 licence in Cargo.toml/LICENSE.

If you want to ship a VST3:

  1. Build with --features vst3.
  2. Relicense your plugin as GPLv3 (or obtain a commercial Steinberg licence) and update Cargo.toml, LICENSE, and the SPDX headers in src/.
  3. Accept Steinberg's VST3 SDK licence.

CLAP has no such restriction.