Tailwind-style utilities with variants — resolved in JS, painted in C++.
Write React.
Ship native VST.
Your TSX runs in an embedded QuickJS engine inside the plugin. A custom reconciler streams the tree to C++, Yoga computes flexbox, juce::Graphics paints every pixel. No webview.
NO WEBVIEW · QUICKJS ES2023 · YOGA FLEXBOX · JUCE::GRAPHICS · WINDOWS · MACOS · LINUX
This UI is React. Drag it.
The window below is a working plugin UI — the same component tree VSReacT paints with juce::Graphics in your DAW, here running as the page itself. Grab a knob. Scroll it. Hover every zone — title bar, badge, meter, canvas, even the hint bar — and watch it trace to its own line of code.
import { useState } from "react";import { render, View, Text, ParamKnob, NativeView } from "@vsreact/core"; function App() { const [hint, setHint] = useState("hover a control"); return ( <View className="flex-1 bg-zinc-950"> <View className="flex-row items-center px-3 py-2"> <Text className="text-xs">VSReacT Gain</Text> <Text className="text-[9] text-red-400">NATIVE</Text> </View> <View className="flex-1 flex-row items-center justify-center gap-10"> <ParamKnob paramId="gain" size={88} /> <ParamKnob paramId="pan" size={88} /> <NativeView nativeId="meter" className="w-12" /> </View> <Text className="text-[10] px-3 py-2">{hint}</Text> </View> );} render(<App />);One component tree: window chrome, hint bar, knobs, and a native meter. Automation-safe host binding included. The arc you just dragged is a painted stroke — in the plugin, C++ paints it at 60fps.
How your tree becomes pixels
- 01React 18
Your TSX, unmodified — hooks, effects, components.
- 02QuickJS
Embedded ES2023 engine, ~1MB, in-process. Zero webview.
- 03Reconciler
Streams the tree to C++ as mutation ops over a C bridge.
- 04Yoga
Real flexbox layout in the native shadow tree.
- 05juce::Graphics
Every pixel painted natively, 60fps, any DAW.
The rest of the toolkit
useParameter(id) binds two-way to the APVTS with automation-safe gestures.
Save, rebuild, the plugin remounts inside the DAW. FL Studio never closes.
A chrome-stripped juce::TextEditor — caret, selection, IME.
<NativeView/> mounts any juce::Component inside the React layout.
Drag gestures with pixel deltas, scroll containers, tweens and springs.
PostHog, native.
Your plugin ships into a world of data — so know which knobs they touch, which panels they open, which presets they load. @vsreact/posthog captures from your React UI and the native bridge delivers over HTTPS, off the audio thread. The API key never enters the JS bundle.
import { usePostHogParameters } from "@vsreact/posthog";
usePostHogParameters(); // every knob your users touchWIRE UP ANALYTICS →A production VST3 whose entire interface is VSReacT — splash screen, live download progress, preview playback, an animated stash drawer. One React codebase. Windows, macOS, Linux.
