Wiki home
From session to plugin

What export actually does

Export compiles your plugin for real: what gets snapshotted, why it takes longer than editing, how signing works, and where the finished bundles go.

Plugin makers who want to understand the build behind the Export button.

While you edit, Patchwerk compiles your patch just-in-time so changes are audible in about a second. Export is a different animal: an ahead-of-time, optimized release build that turns your project into real plugin bundles — CLAP, VST3, Audio Unit, and a standalone app. This page explains what happens between clicking export and a plugin appearing in your DAW. For the click-by-click walkthrough, see Exporting plugins.

A frozen copy of your project goes in

Export does not build "whatever is open" loosely — it assembles a precise snapshot first:

  • Your graph, trimmed. Only the blocks actually reachable from your output are included. Disconnected experiments hanging around the canvas are dead code and get stripped — they cost you nothing in the built plugin.
  • Your samples and wavetables, baked in as part of the bundle.
  • Your custom blocks, compiled along with the built-ins.
  • Your current knob positions. The values you hear in the editor are captured, so the exported plugin boots up sounding exactly like your session — not like factory defaults.
  • Your interface, built for production: the same UI you designed, minus all the editing scaffolding.

Each export runs in its own timestamped folder inside your project, under build/export/run-<timestamp>/, with a full log kept for post-mortems.

Why export takes longer than editing

Editing uses a just-in-time compiler: fast to swap, tuned for iteration. Export instead generates C++ from your patch and compiles it as an optimized release build with link-time optimization — the same kind of build commercial plugins ship with. That is why a one-second edit loop becomes a build measured in minutes, and why the exported plugin performs as well as or better than what you heard in the editor. It is never a downgrade: same DSP, more optimization.

What the Setup Check is actually checking

Export compiles native code on your Mac, so it needs a toolchain:

ToolComes fromIf missing
Cmajor SDKShips inside PatchwerkReinstall the app
CMakeShips inside PatchwerkReinstall the app
Xcode Command Line ToolsApple, freeClick Install — runs Apple's installer

The Setup Check and the export's own preflight step use the exact same detection logic, so a green check means the build will find its tools — the check can never say "ready" while an export would fail at preflight. The Export… menu item stays disabled until everything is green.

Identity: how DAWs recognize your plugin

Your plugin's name, manufacturer, and version live in Project Settings. From those, export derives the identifiers hosts actually key on: a bundle ID, a CLAP ID, and the four-character Audio Unit codes Logic uses to tell plugins apart. The AU codes are generated from a stable hash of your plugin and manufacturer names — the same project always produces the same codes.

That stability matters: when you re-export, DAWs see an update to the same plugin, not a mysterious second one. Your saved sessions keep working. The flip side: rename the plugin or manufacturer and hosts will treat the next export as a brand-new plugin.

Signing: who can run your plugin

macOS requires plugins to be code-signed. Export offers two modes:

  • Ad-hoc (default) — a local signature with no certificate. Perfect for your own machine. On someone else's Mac, Gatekeeper will balk.
  • Developer ID — if you have an Apple Developer ID Application certificate installed, export finds it in your keychain automatically and signs with it. This is the mode for sharing builds with other people. If no certificate is found, export warns and falls back to ad-hoc rather than failing.

Note Notarization (Apple's online malware scan for wide distribution) is a separate step outside Patchwerk. Developer ID signing alone is enough for sharing with collaborators who can right-click-open once.

The proof-of-life test

Near the end of the pipeline, Patchwerk loads your freshly built plugin in a headless host and actually plays it — a note for instruments, a test signal for effects — and checks that audible sound comes out. A build that compiles and signs cleanly but produces silence is a broken export, and this step catches it before it reaches your DAW. If it fails, the usual suspects are DSP wiring (does signal actually reach the output?) and parameter defaults (is something gain-staged to zero?).

The steps you watch go by

StepWhat it is doing
PreflightRe-verifies the toolchain (same logic as Setup Check)
Emit Cmajor patchWrites your snapshotted DSP as a compilable patch
Generate C++Translates the patch into native source code
Build UIProduction build of your plugin interface
Scaffold plugin shellWraps DSP + UI in the native plugin framework
CompileOptimized release build for every selected format
Code signingAd-hoc or Developer ID, per your choice
Validate audio outputThe proof-of-life test above
InstallCopies bundles into your system plugin folders

The pipeline stops at the first failure and the dialog shows you which step broke and why. Everything is also written to a log inside the run folder.

Where everything lands

With Install to system on (the default), finished bundles are copied where DAWs scan:

~/Library/Audio/Plug-Ins/CLAP/        your .clap
~/Library/Audio/Plug-Ins/VST3/        your .vst3
~/Library/Audio/Plug-Ins/Components/  your .component (Audio Unit)

The standalone app is not installed anywhere — it stays in the run folder, ready to launch directly. And every run keeps its complete output under build/export/run-<timestamp>/ inside your project, so you can always grab the raw bundles and move them yourself.

Re-exporting over an installed plugin

Updating is just exporting again: the install step deletes the old bundle and copies the new one in its place. Because the identity codes are stable, your DAW and your saved sessions pick up the new build as the same plugin. When you share updates with others, bump the version in Project Settings first so people can tell builds apart.