Skip to content

Sharing a Project

A project that plays here does not necessarily play there. Your code travels; the sounds it reaches for might not. This guide is about the difference, and about the two things resonon gives you to close it: an entry under [local] in resonon.toml, and resonon collect.

Every kit resonon can find comes from one of four places, and only one of them is a problem.

Where the kit livesTravels?Why
<project>/kits/✅It is inside the project. It goes wherever the project goes.
A package in <project>/dependencies/✅Inside the project, and resonon.toml records it.
The kits that ship with resonon✅Present wherever this version of resonon is installed.
~/.resonon/kits/ — your own kit library❌Yours, and on your machine only.

A folder named in [folders] kits does not travel either — ~/.resonon/preferences.toml is a statement about your machine, not about your piece. See Configuration.

The last row is the one that catches people, and it is the same trap Ableton’s Collect All and Save exists for: your User Library is a wonderful place to keep sounds and a terrible thing to depend on silently.

The kit name is underlined faintly in VS Code the moment you write it, if it resolves to something outside the project that resonon.toml does not account for:

Kit('my-breaks') lives outside this project:
/Users/you/.resonon/kits/my-breaks
It will not be there on another machine.

The lightbulb on that line offers both remedies, so you never have to leave the file:

  • Copy ‘my-breaks’ into this project — the same thing resonon collect my-breaks does.
  • Declare ‘my-breaks’ in resonon.toml — adds it to the kits list, comments and formatting intact.

Either one makes the underline go away. So does editing resonon.toml yourself, or running resonon collect in a terminal: the language server watches both the manifest and <project>/kits, which are the two things that decide the answer.

It is a hint, not a warning: the piece plays either way, and plenty of sketches are never sent anywhere.

A kit name your code computes — Kit(chosen) — gets no underline, because there is no name on the screen to attach one to. Declare those by hand; that is what the list is for.

The first time a piece loads a kit from outside the project that the project has not acknowledged, resonon says so once:

Warning: Kit 'my-breaks' lives outside this project:
/Users/you/.resonon/kits/my-breaks
It will not be there on another machine. To bring it in:
resonon collect my-breaks

Once per kit, per session — not once per evaluation. Kits inside the project, kits from a declared package, and the kits that ship with resonon say nothing at all, because there is nothing to say.

You have two ways to resolve it, and they answer different questions.

Terminal window
resonon collect my-breaks

Copies the kit into <project>/kits/. Your code does not change — <project>/kits is searched before your library, so Kit("my-breaks") now resolves to the project’s own copy. Zip the project folder and it plays anywhere.

This is the answer when the kit is yours: samples you recorded, a kit you built for this piece. Collecting is idempotent and destroys nothing; running it again on a kit that is already in the project reports that and stops. To take a fresh copy after editing the library original, delete <project>/kits/<name> and collect again.

Two things it will refuse, both on purpose:

  • A package’s kit. Kit("drum-kits/808"), or any kit reached through an installed package, already travels — resonon.toml names the package and resonon install fetches it. Copying it in would fork it from its upstream.
  • A kit that reaches outside its own directory. Copying it would not copy all of it, so it is not copied at all. See Kit Configuration.

A kit reaches a project three ways, and only one of them needs writing down:

  • your own material, and collected copies. They sit in <project>/kits and travel because they are already there. Nothing in the manifest.
  • a package. [dependencies] names it, resonon install fetches it back — see Publishing a kit.
  • this machine, with no upstream. That is [local], and it is what this section is about.

[local] kits records the kits this project draws on that came from outside it and cannot be fetched — a pool, in the same way [dependencies] records the code it draws on. resonon collect writes an entry for every kit it brings in, so most of the time you never touch the list by hand.

You do write it by hand for the kit you cannot bring in — a multi-gigabyte library, or content you have no right to redistribute:

[package]
name = "my-song"
[local]
kits = [
"my-breaks",
"field-recordings",
]

One name per line, the way [dependencies] reads. Nothing here ever gains a source: a source is an upstream, and the moment a kit has one it belongs in [dependencies], where there is a lock file and an installer. That is what the section means — the things with no upstream — so there is no second package system hiding in it.

That silences the warning, and it earns its keep on the other machine. Without the entry, someone opening your project gets a not-found error listing ten directories. With it, they get:

Kit 'my-breaks' is listed under [local] in resonon.toml — this project depends on
it from outside itself — but it is not on this machine.
If you have it elsewhere, put it in <project>/kits; if not, ask whoever sent you
this project for it. `resonon kits list` shows everything this project depends on.

That is Missing Media, not a wall.

The entry says where the kit came from, not where it is now — which is why collecting one satisfies its entry rather than spending it.

With no argument, resonon collect works through the whole declared list:

Terminal window
resonon collect

It does not clear the entries as it goes. Collecting satisfies a declaration the way resonon install satisfies a [dependencies] line — the line stays, because it is what says the kit came from outside. Delete kits/my-breaks one day and the project still knows where to look:

Terminal window
resonon collect my-breaks # back again, from the record

On a machine that has only some of the declared kits, you get the ones it has and are told about the rest by name. It collects as far as it can rather than stopping at the first kit it cannot find.

This is why the command needs no arguments and does not have to run your piece: the manifest already holds the answer — including for kits whose names your code computes, which no amount of reading the source could find.

resonon kits list shows every entry and where that kit is right now:

Kits this project depends on from outside it:
Old-808 missing ask whoever sent you this project
my-breaks in this project kits/my-breaks
tape-drums on this machine /Users/you/.resonon/kits/tape-drums
→ resonon collect tape-drums
This project's own kits, in kits/ — they travel, and need no entry:
claps

Three answers, because what you do about each is different. A kit in this project travels already. A kit on this machine is one resonon collect away. A kit that is missing has to come from whoever sent you the project.

If you stop using a kit, drop its line:

Terminal window
resonon kits remove Old-808

Nothing does this for you, and nothing ever will. Kit(…) names can be computed and a live-coded piece runs whatever you evaluate next, so no reading of your source and no record of one session can establish that a kit has stopped being used. The kit’s own files are left where they are — unlike resonon remove, which deletes the package it drops.

You do not have to remember the command. Open resonon.toml in VS Code and every entry carries its own standing at the end of the line:

[local]
kits = [
"my-breaks", in this project
"tape-drums", on this machine
"Old-808", missing
]

The standings are the editor’s, not the file’s — ghost text after each entry, the same four words the command prints.

The two that need something also say so in the Problems panel — a warning for the kit nothing here has, a note for the one still sitting outside the project — and the lightbulb on any entry offers to remove it, or to copy it in where that applies.

Removing an entry here does exactly what resonon kits remove does, including leaving the kit’s own files alone. Your comments and formatting survive: the editor writes the file through the same careful writer the command uses.

If you made a kit other people should have, do not ask them to collect it — make it a package. A package ships its kits in kits/, and those directories are part of the kit search path, so an installed package’s kits resolve by their bare names:

Terminal window
resonon install gh:you/tape-drums
let k = Kit("tape-drums");

Now it is in [dependencies], resonon.lock pins the commit, and anyone running resonon install gets the same bytes. This is the mechanism for anything meant to be shared, and it is why the kits list never grows a source field: the moment there is a source, the entry belongs in [dependencies].

See Package Management for creating and publishing one.

  1. Play the piece. Note any kit resonon warns about.
  2. resonon collect — brings in everything declared, and tells you what it did.
  3. resonon kits list — anything still missing is a kit the recipient will not have either.
  4. resonon config paths — shows every directory resonon searches, and where each came from.
  5. Zip the project directory. dependencies/ can be left out; resonon install rebuilds it from resonon.toml and resonon.lock.