Skip to content

Search Paths & Portability

A piece reaches for content — kits, modules, samples, plugins — and the same source should sound the same on every machine it is opened on. This page explains how resonon finds that content so that this machine’s folders can help a piece without being able to change it.

Folders are a list you can take things out of

Section titled “Folders are a list you can take things out of”

resonon setup has a page for each folder list, and resonon config kits / plugins edit them without opening the file. The list is the truth, so taking an entry out takes it out of the search — something a list that only ever grew could never say.

Only ~ is expanded. A stored path read by the CLI, by the language server and by a CI shell would name a different folder in each if it could name an environment variable or be relative, which is the whole problem preferences exist to fix. $NAME still works in export() and plugin_rescan(), which are gestures inside one running process.

A folder you name is searched in addition to the built-in ones. Naming a kit folder of your own never takes the standard ones away, so adding one cannot make the bundled kits disappear.

The order — the project, then this machine’s folders, then the resonon home — is listed in Home & Search Paths.

The project comes first so that a project defines itself: a folder your rig happens to have cannot change what somebody else’s project resolves, and the same source sounds the same on every machine. Your own folders still shadow the installed ones, which is where shadowing is useful.

This is also why a folder list is safely data. It is additive, and ranked below the project’s own content, so it cannot change how a portable piece sounds — only whether a piece that was already reaching outside itself finds what it was reaching for.

resonon config paths prints the resolved list, and the editor resolves modules through the same one, so a use that works when you run a file also hovers, jumps and completes.

There is no machine-wide module path, and no setting that adds one. A module is reachable because this project’s resonon.toml declares the package it lives in and resonon install put it in dependencies/, or because a use names it by a relative path — never because of anything on this machine. A piece depends on nothing it has not recorded, so the same source resolves the same way everywhere. Modules lists how a use path resolves.

Sample files are not searched for at all. Sample("kick.wav") is a path, not a name: it resolves relative to the .non file that names it — the way use and load_file do — and an absolute path is taken as given. There is no list, so a sample either sits where your piece says it sits or it does not exist, and no folder anyone adds can change which file a piece plays. A kit is the other kind of thing: Kit("808") is a name, and a name is what gets looked up in the search order. To reach one hit out of a kit, go through the kit rather than through a path that happens to land inside one:

Sampler(Kit("CR-78")).sample("bd")

"bd" is the name the kit gives that sound, not the name of a file inside it — which is the point: the kit decides what its sounds are called, so a piece written against it keeps working when the kit’s files are renamed or replaced.

A kit found through a [folders] kits entry is still outside the project, and still says so: naming the folder makes the kit load, it does not make the piece portable. resonon collect is what brings one in.

A project’s code always travels. The sounds it reaches for travel only if they come from somewhere that exists on the other machine too:

Where the kit livesTravels?Why
<project>/kits/YesIt is inside the project.
A package in <project>/dependencies/Yesresonon.toml names it, and resonon install fetches it again.
The kits that ship with resononYesThey are wherever this version of resonon is installed.
~/.resonon/kits/, or a [folders] kits entryNoThey are on this machine only.

A kit travels as a unit because nothing in it points outside it: every path a kit.toml names is relative and stays under the kit’s samples/. That is what lets a kit be copied into a project, by hand or with resonon collect, and still play. A kit that pointed at /Users/you/samples/kick.wav would work on your machine and silently fall apart on anyone else’s, so resonon refuses to load one.

The last row is the trap Ableton’s Collect All and Save exists for: a user library is a good place to keep sounds and a bad thing to depend on silently. So resonon says so, once per kit, and offers two answers — bring the kit into the project with resonon collect, or record under [local] that the project needs it from outside.

[local] is the counterpart of [dependencies]: the things a project draws on that have no upstream. That is why an entry never gains a source. The moment a kit has somewhere to be fetched from, it is a package and belongs in [dependencies], with a lock file and an installer — so there is no second package system hiding in [local]. And the entry says where a kit came from, not where it is now, which is why collecting a kit satisfies its entry rather than removing it.

Nothing ever removes an entry for you. A Kit(…) name can be computed, and a live-coded piece runs whatever you evaluate next, so no reading of the source and no record of one session can prove a kit is no longer used.