NodeProxy and Ndef are SuperCollider's server-side placeholders whose synthesis source can be swapped while playing
In SuperCollider’s JITLib, a proxy is an object that plays as a placeholder even before its synthesis function is fully defined, and can be redefined live. NodeProxy is the base class: it wraps a UGen function in a persistent server node that keeps running when the function is replaced. Ndef is the def-style access layer — it binds a symbol to a NodeProxy in a global registry, making that proxy addressable by name from anywhere in the session; Ndef is the idiomatic interactive form, NodeProxy the lower-level base it uses internally. You assign a new .source (a Function, SynthDef, or pattern) and the running audio crossfades to it with no gap, and .set changes a parameter without stopping. This is the core enabler of gapless live-coded improvisation. JITLib also offers ProxySpace, which turns environment variables into proxies for concise ~x = { … } syntax. The key contrast: x = {SinOsc.ar(440)}.play cannot be redefined in place, whereas an Ndef can.
Examples
Ndef(\pad, { |freq=440| SinOsc.ar(freq) * 0.3 ! 2 }).play; Ndef(\pad).set(\freq, 220); // change a param, no gap Ndef(\pad, { Saw.ar(220) * LFNoise1.kr(1).range(0, 0.2) ! 2 }); // swap source, crossfades
Assessment
Create an Ndef that plays a drone, change its frequency without stopping the audio, then replace its source function with a different waveform. Explain the behavioral difference between x = {SinOsc.ar(440)}.play and Ndef(\x, {SinOsc.ar(440)}).play when you want to change the sound mid-playback.