VSTv0.0.17
A REACT RENDERER FOR JUCE AUDIO PLUGINS

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

THE PROOF IS BELOW — DRAG IT

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.

VSReacT GainNATIVE
+0.0 dBGAIN
CPAN
hover any zone to trace it to the 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

  1. 01React 18

    Your TSX, unmodified — hooks, effects, components.

  2. 02QuickJS

    Embedded ES2023 engine, ~1MB, in-process. Zero webview.

  3. 03Reconciler

    Streams the tree to C++ as mutation ops over a C bridge.

  4. 04Yoga

    Real flexbox layout in the native shadow tree.

  5. 05juce::Graphics

    Every pixel painted natively, 60fps, any DAW.

The rest of the toolkit

Classes you know

Tailwind-style utilities with variants — resolved in JS, painted in C++.

Host-grade params

useParameter(id) binds two-way to the APVTS with automation-safe gestures.

~100ms hot reload

Save, rebuild, the plugin remounts inside the DAW. FL Studio never closes.

Real text input

A chrome-stripped juce::TextEditor — caret, selection, IME.

Native escape hatch

<NativeView/> mounts any juce::Component inside the React layout.

Motion built in

Drag gestures with pixel deltas, scroll containers, tweens and springs.

READ THE FULL DOCUMENTATION →
IN A WORLD OF DATA

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 touch
WIRE UP ANALYTICS →
SHIPPING — NOT A DEMOStashTrack runs its whole UI on this.

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.