VST3 SDK and VSTGUI implementation patterns. Use when working on plugin UI, parameter handling, VSTGUI components, editor lifecycle, thread safety, controller code, reusable view templates, sub-controllers, or cross-platform compatibility. Covers parameter types, IDependent pattern, visibility controllers, control selection, template instantiation, tag remapping, and common pitfalls. Use when this capability is needed.
This skill captures hard-won insights about VST3 SDK and VSTGUI that are not obvious from official documentation. These findings prevent repeating debugging sessions that waste hours.
Quick Reference
Parameter types & helpers: See PARAMETERS.md
Thread safety, IDependent & DataExchange API: See THREAD-SAFETY.md
VSTGUI components & reusable templates: See UI-COMPONENTS.md
Control selection guide: See CONTROLS-REFERENCE.md
Cross-platform patterns: See CROSS-PLATFORM.md
Common pitfalls & incidents: See PITFALLS.md
Framework Philosophy
When something doesn't work with VSTGUI or VST3 SDK:
The framework is correct - It's used in thousands of commercial plugins
You are using it wrong - The bug is in your usage, not the framework
Read the source - The SDK and VSTGUI are open source; read them
Use SDK functions - Don't reinvent conversions the SDK already provides
Trust automatic bindings - template-switch-control, menu population, etc.
Key Principles
Parameter Types Matter
The base Parameter class does NOT scale normalized values in toPlain() - it just returns the input unchanged. Use:
Use Case
Parameter Type
Continuous knob (0-1 range)
Parameter
Continuous range (e.g., 20Hz-20kHz)
RangeParameter
Discrete list (e.g., modes, types)
StringListParameter
See PARAMETERS.md for details.
Thread Safety is Non-Negotiable
setParamNormalized() can be called from ANY thread (automation, state loading, etc.). VSTGUI controls MUST only be manipulated on the UI thread.
NEVER do this:
// BROKEN - setParamNormalized can be called from any thread!
tresult Controller::setParamNormalized(ParamID id, ParamValue value) {
if (id == kTimeModeId) {
delayTimeControl_->setVisible(value < 0.5f); // CRASH!
}
}
ALWAYS use the IDependent pattern with deferred updates. See THREAD-SAFETY.md.
Feedback Loop Prevention (Built-in)
VST3Editor already prevents feedback loops in valueChanged():
void VST3Editor::valueChanged(CControl* pControl) {
if (!pControl->isEditing()) // Only propagates USER edits
return;
// ... send normalized value to host
}
isEditing() == true: User is actively manipulating the control
isEditing() == false: Host is updating programmatically
You don't need custom feedback prevention code. VSTGUI handles this automatically.
PITFALLS.md - Common mistakes, incident log, debugging lessons
Converted and distributed by TomeVault — claim your Tome and manage your conversions.
1---2name: vst-guide3description: VST3 SDK and VSTGUI implementation patterns. Use when working on plugin UI, parameter handling, VSTGUI components, editor lifecycle, thread safety, controller code, reusable view templates, sub-controllers, or cross-platform compatibility. Covers parameter types, IDependent pattern, visibility controllers, control selection, template instantiation, tag remapping, and common pitfalls. Use when this capability is needed.4---56# VST3 SDK and VSTGUI Implementation Guide78This skill captures hard-won insights about VST3 SDK and VSTGUI that are not obvious from official documentation. These findings prevent repeating debugging sessions that waste hours.910## Quick Reference1112- **Parameter types & helpers**: See [PARAMETERS.md](PARAMETERS.md)13- **Thread safety, IDependent & DataExchange API**: See [THREAD-SAFETY.md](THREAD-SAFETY.md)14- **VSTGUI components & reusable templates**: See [UI-COMPONENTS.md](UI-COMPONENTS.md)15- **Control selection guide**: See [CONTROLS-REFERENCE.md](CONTROLS-REFERENCE.md)16- **Cross-platform patterns**: See [CROSS-PLATFORM.md](CROSS-PLATFORM.md)17- **Common pitfalls & incidents**: See [PITFALLS.md](PITFALLS.md)1819---2021## Framework Philosophy2223When something doesn't work with VSTGUI or VST3 SDK:24251. **The framework is correct** - It's used in thousands of commercial plugins262. **You are using it wrong** - The bug is in your usage, not the framework273. **Read the source** - The SDK and VSTGUI are open source; read them284. **Use SDK functions** - Don't reinvent conversions the SDK already provides295. **Trust automatic bindings** - template-switch-control, menu population, etc.3031---3233## Key Principles3435### Parameter Types Matter3637The base `Parameter` class does NOT scale normalized values in `toPlain()` - it just returns the input unchanged. Use:3839| Use Case | Parameter Type |40|----------|---------------|41| Continuous knob (0-1 range) | `Parameter` |42| Continuous range (e.g., 20Hz-20kHz) | `RangeParameter` |43| Discrete list (e.g., modes, types) | `StringListParameter` |4445See [PARAMETERS.md](PARAMETERS.md) for details.4647### Thread Safety is Non-Negotiable4849`setParamNormalized()` can be called from **ANY thread** (automation, state loading, etc.). VSTGUI controls MUST only be manipulated on the UI thread.5051**NEVER** do this:52```cpp53// BROKEN - setParamNormalized can be called from any thread!54tresult Controller::setParamNormalized(ParamID id, ParamValue value) {55 if (id == kTimeModeId) {56 delayTimeControl_->setVisible(value < 0.5f); // CRASH!57 }58}59```6061**ALWAYS** use the `IDependent` pattern with deferred updates. See [THREAD-SAFETY.md](THREAD-SAFETY.md).6263### Feedback Loop Prevention (Built-in)6465VST3Editor already prevents feedback loops in `valueChanged()`:6667```cpp68void VST3Editor::valueChanged(CControl* pControl) {69 if (!pControl->isEditing()) // Only propagates USER edits70 return;71 // ... send normalized value to host72}73```7475- `isEditing() == true`: User is actively manipulating the control76- `isEditing() == false`: Host is updating programmatically7778**You don't need custom feedback prevention code.** VSTGUI handles this automatically.7980---8182## Source Code Locations8384| Component | Location |85|-----------|----------|86| Parameter classes | `extern/vst3sdk/public.sdk/source/vst/vstparameters.cpp` |87| VST3Editor | `extern/vst3sdk/vstgui4/vstgui/plugin-bindings/vst3editor.cpp` |88| UIViewSwitchContainer | `extern/vst3sdk/vstgui4/vstgui/uidescription/uiviewswitchcontainer.cpp` |89| UIDescription (templates) | `extern/vst3sdk/vstgui4/vstgui/uidescription/uidescription.h` |90| IController (sub-controllers) | `extern/vst3sdk/vstgui4/vstgui/uidescription/icontroller.h` |91| DelegationController | `extern/vst3sdk/vstgui4/vstgui/uidescription/delegationcontroller.h` |92| COptionMenu | `extern/vst3sdk/vstgui4/vstgui/lib/controls/coptionmenu.cpp` |93| CViewContainer | `extern/vst3sdk/vstgui4/vstgui/lib/cviewcontainer.cpp` |94| CView | `extern/vst3sdk/vstgui4/vstgui/lib/cview.cpp` |9596---9798## Debugging Checklist99100When VSTGUI/VST3 features don't work:1011021. [ ] Add logging to trace actual values at each step1032. [ ] Check which parameter type you're using (`Parameter` vs `StringListParameter` vs `RangeParameter`)1043. [ ] Verify `toPlain()` returns expected values1054. [ ] Read the VSTGUI source in `extern/vst3sdk/vstgui4/vstgui/`1065. [ ] Read the VST3 SDK source in `extern/vst3sdk/public.sdk/source/vst/`1076. [ ] Check if automatic bindings are configured correctly in editor.uidesc1087. [ ] Verify control-tag names match parameter registration109110---111112## Additional Resources113114For detailed information, see the supporting files:115116- [PARAMETERS.md](PARAMETERS.md) - Parameter types, toPlain(), dropdown helpers, StringListParameter117- [THREAD-SAFETY.md](THREAD-SAFETY.md) - IDependent pattern, visibility controllers, editor lifecycle118- [UI-COMPONENTS.md](UI-COMPONENTS.md) - UIViewSwitchContainer, COptionMenu, CViewContainer visibility119- [CONTROLS-REFERENCE.md](CONTROLS-REFERENCE.md) - Control selection decision matrix, XML examples120- [CROSS-PLATFORM.md](CROSS-PLATFORM.md) - Custom views, file dialogs, paths, fonts121- [PITFALLS.md](PITFALLS.md) - Common mistakes, incident log, debugging lessons122123---124> Converted and distributed by [TomeVault](https://tomevault.io/claim/rolandzwaga) — claim your Tome and manage your conversions.125<!-- tomevault:4.0:skill_md:2026-04-13 -->
Run npx skillmds@latest add tomevault-io/vst-guide in your terminal (requires Node.js), paste this page's agent-chat prompt into Claude, Cursor, or any MCP-connected agent, or download the SKILL.md file and copy it into your agent's skills directory.
VST3 SDK and VSTGUI implementation patterns. Use when working on plugin UI, parameter handling, VSTGUI components, editor lifecycle, thread safety, controller code, reusable view templates, sub-controllers, or cross-platform compatibility. Covers parameter types, IDependent pattern, visibility controllers, control selection, template instantiation, tag remapping, and common pitfalls. Use when this capability is needed. It is listed under Coding & Dev Tools on SkillMD.
This skill has not completed SkillMD's automated safety review yet. Independent scanners report: SkillSpector: PASS, Skill Scanner: PASS. SkillMD never runs a skill's scripts for you; review the SKILL.md before installing.
This skill is tagged as working with Claude Code, Claude.ai, OpenAI Codex. SKILL.md is an open format, so most agents that read a skills directory can load it too.
Yes. Installing skills from SkillMD is free, and the skill stays under its author's original license.
tomevault-io (@tomevault-io) published this skill. Their other Agent Skills are listed on their SkillMD profile.