Constraints for plugin developers
The few rules Maru's architecture depends on, for developers coming from JUCE or another framework, with links to the guides that own the details.
If you have built plugins before, most of Maru will feel familiar: parameters, presets, audio and MIDI processing, a UI and a set of plugin formats. A few rules differ, and they are what let one source play in a browser, a DAW and other targets. This page names them. The details belong to the linked guides, and they evolve as the platform does.
Realtime code stays realtime
Sound processing is written as restricted TypeScript that compiles to each target. The audio callback must not allocate, lock, block or do I/O. State is prepared ahead of processing, and controls change through the building blocks' own setters. Model inference, file access and network calls happen outside it. See the Audio SDK and DSP library.
A module owns the sound; the host owns services
A module declares its ports, parameters, presets, assets and interface. Devices, files, sign-in, account access and other services come from the host. Faces never produce audio or open devices. See How it works.
Parameters mean the same thing everywhere
Each parameter's range, steps and response curve are declared once, on the parameter. Host automation, MIDI CC and the interface all read that declaration, so they agree position for position. Shape a parameter's feel there, not in the face. See Contracts.
One source, qualified targets
The browser, native plugin formats and devices are built from the same source. Each target is built and checked separately, and each release lists what it supports. A browser demo does not by itself establish a native or hardware target. See Check, build and export and Native plugins.
Reuse before writing new DSP
Prefer the library's effects and building blocks, and extend a shared building
block rather than copying it into a module. maru dsp effects, maru dsp nodes
and maru module list show what exists. See
Effects, instruments and custom DSP.
Porting an existing plugin
A JUCE effect maps onto one Processor module. Scaffold it with
maru init <name> --kind processor-effect, then read the guides the CLI
ships: maru guide read processor-authoring restricted-typescript parameters-and-schema presets-and-state build-preview-export. They cover the
contract and are versioned with your installed CLI.
| In the JUCE plugin | In the Maru module |
|---|---|
prepareToPlay / processBlock / reset | prepare / process / reset in src/dsp/processor.ts |
AudioProcessorValueTreeState parameters | the schema in src/contract.ts; keep the original ids and ranges |
| factory presets / programs | presets: [{ id, name, values }] on the declaration |
| stereo bus layout | channels: 2 on defineEffect; an effect is mono when it is omitted |
| editor | a face in src/ui/, built from UI-kit controls bound to parameters |
| unit tests against golden data | a script that drives your Processor, plus maru render on the packed Release |
Four rules catch most ports:
- Declare stereo. Without
channels: 2the module is mono, and the checks pass anyway.maru renderwith a stereo file is the first thing that refuses it. - Output must not depend on block size. If the original splits each host block into fixed sub-blocks (for example 64-sample coefficient updates), count them on the audio stream instead. That keeps the result the same for any host block size.
resetmust return the instance to its freshly created sound. A value the original kept across resets has to be cleared; the check names it.- Keep the original parameter mapping when you need fidelity. If the original maps a 0..1 control through its own curve, keep the 0..1 parameter and the curve in the DSP, and show the unit (Hz, dB) in the face.
Then prove the port: render the original's test input through the packed
Release with maru render and compare against the original's output or
golden values, see Check, build and export.
Publish with maru publish, see
Publish to maruaudio.com. If the
original is under a copyleft license such as GPL or AGPL, your port is a
derivative work: keep its license and attribution, and choose the listing
license to match.
Availability and licensing
The maruaudio package is published on npm. The local workbench and plugin
builds currently need a toolchain provided in the selected-developer beta; see
the Quickstart. The SDK, CLI and generated plugin shells are
not published under a general open-source license; see
Licensing. Choosing Maru compares the
approach with JUCE, Cmajor and RNBO.