Skip to content
Development
Skill

/juce-guide

Step-by-step guide for building a JUCE audio plugin from scratch. Use when the user asks "how do I create a JUCE plugin", "set up a JUCE project", "add parameters to my JUCE plugin", "package my VST3", or "how do I wire up APVTS". Trigger on phrases like "create a JUCE plugin",

From plugin
sonic-skills
2018 skills
Install
$ npx -y skills add kunitoki/sonic-skills --skill juce-guide --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/juce-guide

Context preview

The summary Claude sees to decide when to auto-load this skill.

Step-by-step guide for building a JUCE audio plugin from scratch. Use when the user asks "how do I create a JUCE plugin", "set up a JUCE project", "add parameters to my JUCE plugin", "package my VST3", or "how do I wire up APVTS". Trigger on phrases like "create a JUCE plugin",

SKILL.md

juce-guide.SKILL.md
name: juce-guide
description: >
  Step-by-step guide for building a JUCE audio plugin from scratch. Use when the user
  asks "how do I create a JUCE plugin", "set up a JUCE project", "add parameters to my
  JUCE plugin", "package my VST3", or "how do I wire up APVTS". Trigger on phrases like
  "create a JUCE plugin", "JUCE CMake setup", "AudioProcessor skeleton", "add APVTS
  parameters", or "codesign my plugin on macOS".

JUCE Audio Plugin — Build Guide

Five steps from empty folder to distributable plugin. Do each step in order; skip none.

Step 1 — Project setup (CMake + JUCE)

  • Add JUCE as a git submodule or FetchContent target; call `add_subdirectory(JUCE)`.
  • Use `juce_add_plugin(MyPlugin FORMATS VST3 AU Standalone ...)` to declare the plugin target.
  • Set `PLUGIN_MANUFACTURER_CODE`, `PLUGIN_CODE`, `IS_SYNTH`, `NEEDS_MIDI_INPUT` in the same call.
  • Link `juce::juce_audio_processors juce::juce_audio_utils juce::juce_dsp` to the target.

Step 2 — AudioProcessor skeleton

  • Subclass `juce::AudioProcessor`; override `prepareToPlay`, `releaseResources`, `processBlock`.
  • In `prepareToPlay`: store `sampleRate` and `maximumBlockSize`, allocate internal buffers, reset all state (filters, envelopes, delay lines — unconditionally).
  • In `processBlock`: read only pre-cached raw parameter pointers; never allocate, never call JUCE String ops or DBG().
  • Implement `getStateInformation` / `setStateInformation` using `apvts.copyState()` and `apvts.replaceState()` with a `MemoryOutputStream` / `MemoryBlock`.

Step 3 — Parameters via APVTS

  • Declare a static `createParameterLayout()` method that returns `AudioProcessorValueTreeState::ParameterLayout`.
  • Construct `apvts(*this, nullptr, "Parameters", createParameterLayout())` as a member.
  • After constructing APVTS, cache raw pointers once: `gainParam = apvts.getRawParameterValue("Gain")`.
  • In `processBlock`, dereference with `gainParam->load()` — no APVTS calls on the audio thread.
  • Use `AudioProcessorValueTreeState::ParameterAttachment` (or `SliderAttachment`) in the editor, never in the processor.

Step 4 — Editor and UI

  • Subclass `juce::AudioProcessorEditor`; call `setSize(w, h)` in the constructor.
  • Override `paint` for background / labels; override `resized` to lay out components with `setBounds`.
  • Declare `juce::Slider` members; attach each via `juce::AudioProcessorValueTreeState::SliderAttachment`.
  • Keep all UI state in the editor — the processor must function correctly with no editor open.
  • The editor holds a reference to the processor (passed in constructor); never store a raw editor pointer in the processor.

Step 5 — Build, test, package

  • Configure: `cmake -B build -DCMAKE_BUILD_TYPE=Release`
  • Build: `cmake --build build --config Release`
  • Locate artefacts under `build/MyPlugin_artefacts/Release/`.
  • macOS codesign: `codesign --deep --force --sign "Developer ID Application: ..." MyPlugin.vst3` then `spctl --assess --verbose MyPlugin.vst3`.
  • Notarize for distribution: `xcrun notarytool submit MyPlugin.pkg --apple-id ... --wait`.
  • Validate in a DAW host or use the JUCE `AudioPluginHost` utility (`extras/AudioPluginHost`).

Common pitfalls

| Pitfall | Correct approach | |---------|-----------------| | Calling `apvts.getParameter()` in `processBlock` | Cache `getRawParameterValue()` once after APVTS construction | | Allocating in `processBlock` | Allocate in `prepareToPlay` only | | Not resetting state on `prepareToPlay` re-entry | Always reset unconditionally | | Storing editor pointer in processor | Use `createEditor()` factory; processor owns no editor reference | | Missing `JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR` | Add to every `AudioProcessor` and `AudioProcessorEditor` subclass |

Use the `juce-review` skill to audit finished processor code for thread-safety violations.

Read more
Ships withsonic-skills

Precision audio-engineering skills for AI agents. Sonic Skills is a curated pack of Markdown skills for reviewing, debugging, explaining, and implementing audio software.

Get the whole plugin
Stats
20
Stars
1
Forks
Maintained
Maintenance
Shell
Language
Unlicense
License
4mo ago
Last commit
4mo ago
Created

Repo: kunitoki/sonic-skills

Other skills on sonic-skills.