# Faust DSP: the second abstraction

FaustWave gives you two ways to build sound, and both end in the same place:
a **DSP** — a compiled Faust worklet, running. The **Builder** is the visual
route — nodes and cables, no code in sight. A **Faust DSP** (`.dsp`) is the
same engine with the covers off: you write [Faust](https://faust.grame.fr)
source in a Monaco editor, hit Run, and the IDE compiles it to WebAssembly
and runs it as an AudioWorklet — exactly as a Builder does, because under the
hood a Builder *generates* Faust source too.

The word matters here, so it is worth being exact: **"DSP" is what runs**,
and `builder` and `faust-dsp` are the two documents that produce one. The
action families follow that split — `builder.*` edits a graph, `dsp.*` drives
whatever is running, either kind.

When to reach for a `.dsp` instead of the Builder:

- **The stock nodes can't express it.** Pitch envelopes, wavetable
  switching, frame-rate steppers, custom feedback topologies — anything the
  node catalog doesn't cover is a few lines of Faust.
- **You want the whole `stdfaust.lib` universe.** Every oscillator, filter,
  envelope, reverb and physical model in the Faust standard library is one
  `import("stdfaust.lib");` away.
- **You think in code.** A DSP is a plain text file — diffable,
  versionable, forkable on the Hub as `kind: "dsp"`.

What you do NOT give up: the mixer strip, the Patchbay routing, MIDI,
modulation, the sequencer — a running `.dsp` is a first-class citizen
of the same audio graph.

## Lifecycle in one paragraph

`documents.add { type: "faust-dsp" }` creates the module **and its project
file** immediately (auto-placed in the project's `assets/`, autosaved on
every edit). Run compiles + starts the worklet; Stop disposes it but keeps
the mixer strip. Editing while running does NOT hot-swap — Stop + Run to
hear changes. The file lives with your project and travels with a project
export.

> 🟦 **DISCOVER FROM CODE**: `documents.list {}` returns every open `.dsp`
> module with its runtime state — `running`, `status`, `compile_error`,
> `polyphonic`, `midi_channel`, and the live param paths. It's the first
> call the assistant makes before touching any DSP.
