A DAW at 5% CPU, using nothing but stock WebAudio nodes
No AudioWorklet, custom DSP, or WebAssembly. No dependencies, package manager, or build pipeline either (beyond a CoffeeScript compiler). A heavy production runs at around 5% CPU on a cheap laptop.
This page explains how it is done, partly because it is interesting and partly because anyone thinking about maintaining this codebase would want to know.
Only standard nodes
The conventional route to a serious browser audio application is AudioWorklet: DSP in JavaScript or WebAssembly, run on the audio thread. Xequence Audio uses standard WebAudio nodes instead: oscillators, filters, gains, delays, convolvers, waveshapers, analysers.
The payoff is that all the actual signal processing happens in the browser's own natively compiled, heavily optimized code (huge shoutout to the Chromium audio team for optimizing this so well).
The downside is a bit less flexibility and a few more weird hacks required to get specialized functionality sometimes.
Dynamic audio graph
A naive implementation might allocate every voice of every instrument up front and leave them running all the time. That is simple, but comes with significant performance problems in larger projects.
In Xequence Audio, the audio graph is dynamic: Nodes are created when a voice needs them and disposed of when it has finished, so the graph is always roughly the size of what is actually audible rather than the size theoretically needed for all instruments at maximum polyphony.
Constructing and tearing down nodes is expensive, so frequently used nodes are cached and reused rather than reallocated.
Scheduling slightly into the future
WebAudio parameter changes applied "now" are applied whenever the control thread happens to get around to it, which would give unacceptably sloppy and inconsistent timing.
Xequence Audio thus schedules every dynamic node configuration and every parameter change at an explicit timestamp slightly in the future, which the audio thread then honours exactly. The result is sample-accurate automation and oscillator / LFO sync (live input is also pushed a small distance into the future rather than fired immediately to inherit the same precise timing / sync).
The codebase
- ~50,000 lines of CoffeeScript across 38 modules, for both logic and interface.
-
~4,000 lines of CSS. The entire interface is straightforward HTML and CSS, except for the arranger and pianoroll editing canvases, which use
<canvas>. - Straightforward procedural code. No class hierarchies, dependency injection, or inheritance. Objects are only used for data storage and as namespaces. Basically as in the 90s.
- Descriptive names, comments where intent is not obvious.
- No dependencies whatsoever. Clone it, compile the CoffeeScript, open in browser.
On CoffeeScript: it compiles to readable JavaScript, and running
decaffeinate across the whole tree as a single commit before
any other work is a perfectly reasonable first move for a new
maintainer, as I suspect most would find CoffeeScript too "outdated" (and too elegant 😄).
Pragmatic and also somewhat brilliant
Relative automation
Automation in Xequence Audio is always an offset, from −100% to +100% of the parameter's range, added to whatever the respective fader or slider is currently set to. This means that faders and sliders still work as expected even with written automation, you can rebalance a mix after the automation is written, and the automation just rides along with your change instead of overwriting it. This decision alone removed an entire category of frustration with existing DAWs for me.
The patch is the interface
Hybris, the modular synth, has no separately designed front panel. The modules you add and the way you lay them out are the user interface. That also means that adding a new module type does not require any significant UI work apart from layout out a few (standardized) sliders and buttons.
Caveats for you as a maintainer
- There are currently no unit tests. There is a set of MIDI and project files that contains "unusual" data that has triggered bugs in the past, but nothing structured.
-
It is currently CoffeeScript, which is a minority language in 2026. See
above regarding
decaffeinate. - Audio tracks do not exist yet. The foundation exists however: the Hybris sample modules already chase notes and apply correct sample offsets. The remaining work is exposing sample players as tracks, adding a special audio clip type, showing waveform previews, and building the recording infrastructure.
- MIDI is currently iOS-only. The implementation is thorough and well-tested but currently only has a CoreMIDI bridge (not included in the open-source project). Adding WebMIDI support is only a matter of adding a simple adapter to the existing MIDI queue implementation. It is also on the funding ladder in case money arrives before maintainers! 😉
- Tested and used in production mostly on Chromium. That is basically 100% of real-world browsers in 2026, but in case people want to reliably use Xequence Audio in Firefox and others, some testing / workarounds might be needed.