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", "JUCE CMake setup", "AudioProcessor skeleton", "add APVTS parameters", or "codesign my plugin on macOS".From its SKILL.md
npx -y skills add kunitoki/sonic-skills --skill juce-guideAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- 15 stars15 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
- runs commandsInstructs the agent to run 5 commands, including `cmake -B build -DCMAKE_BUILD_TYPE=Release` and 4 more.
SKILL.md
3.8 KB, 844 tokens by cl100k_base, as published. Nobody here has run it
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_INPUTin the same call. - Link
juce::juce_audio_processors juce::juce_audio_utils juce::juce_dspto the target.
Step 2 — AudioProcessor skeleton
- Subclass
juce::AudioProcessor; overrideprepareToPlay,releaseResources,processBlock. - In
prepareToPlay: storesampleRateandmaximumBlockSize, 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/setStateInformationusingapvts.copyState()andapvts.replaceState()with aMemoryOutputStream/MemoryBlock.
Step 3 — Parameters via APVTS
- Declare a static
createParameterLayout()method that returnsAudioProcessorValueTreeState::ParameterLayout. - Construct
apvts(*this, nullptr, "Parameters", createParameterLayout())as a member. - After constructing APVTS, cache raw pointers once:
gainParam = apvts.getRawParameterValue("Gain"). - In
processBlock, dereference withgainParam->load()— no APVTS calls on the audio thread. - Use
AudioProcessorValueTreeState::ParameterAttachment(orSliderAttachment) in the editor, never in the processor.
Step 4 — Editor and UI
- Subclass
juce::AudioProcessorEditor; callsetSize(w, h)in the constructor. - Override
paintfor background / labels; overrideresizedto lay out components withsetBounds. - Declare
juce::Slidermembers; attach each viajuce::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.vst3thenspctl --assess --verbose MyPlugin.vst3. - Notarize for distribution:
xcrun notarytool submit MyPlugin.pkg --apple-id ... --wait. - Validate in a DAW host or use the JUCE
AudioPluginHostutility (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.
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.