Skip to main content
Most apps are more than one service, and each service expects to find the others at a fixed localhost port. Tesser keeps that arrangement on the box. A dependency is a loopback port declared in the manifest, and Tesser connects that port to the right instance of the other service, wherever it is actually running.
The app keeps its existing API_URL=http://localhost:5001 and nothing in it needs to change.

Which instance a dependency reaches

A dependency names a service, not a box. The rule has no special cases: a dependency reaches the box you wired it to, otherwise the org’s shared instance of that service (described below), and otherwise nothing — dev still starts the server and prints a warning that the dependency has nothing behind it, and connections to the port fail loud. Nothing is ever wired automatically. Two boxes only talk to each other because someone pointed one at the other:
This works the same whether the two services live in one repository or two — a wire connects boxes, and it does not matter which worktree they came from. A shared instance’s dependencies never resolve to anyone’s dev box, so work in progress on one person’s branch cannot affect a teammate.

Reaching a box by name

A wire is for code that expects a fixed localhost port. Code that is happy to name the box can skip the wire entirely: on any of your boxes, http://<box_id>.localhost:<port> reaches that box’s declared port, the same address the laptop uses. This is a convenience for scripts and one-off checks, not a substitute for a dependency, and a port the target does not declare in its manifest is refused. Every instance box in the org has one, the shared instances included: a shared instance can dial a dev box that handed it its address, which is how a dev box registers for webhooks. That is separate from what a dependency resolves to, described above — a shared instance’s own deps still never reach anyone’s dev box. See localhost.

The shared instance

A shared instance runs one service at one specific commit, with no laptop involved. It is what everyone’s boxes use for the services they are not currently working on.
This creates a box, checks out that commit on it, runs setup and dev, waits for the health check to pass, and makes the box the org’s shared instance of api. Running the command again with the same commit does nothing and prints the same box id. Running it with a new commit starts a new box, waits until the new box is healthy, switches the shared instance over, and then removes the old box. To roll back, run it again with the previous commit. Usually CI runs this for each service on every push to main. The box belongs to the org rather than to a person, so it cannot be synced to, and its env values come from tesser env set rather than from a file (see Services). dev starts only the requested service. Verify its dependencies are running; use ensure-running to create missing shared instances.

Wiring a dependency

The first command points one box’s api dependency at a box you choose: your own dev box of api, a teammate’s box, or an older build. --shared returns it to the org’s shared instance, and the bare form shows where every dependency of the box currently points. The panel shows each box’s dependency graph and the resolved laptop routes. Laptop selection can override individual subtrees without changing these wires. A wire names a box, and it stays put: if the target box is later removed, the dependency fails loud rather than silently falling back to the shared instance. Re-wire it, or return it to --shared. To see a backend change through a frontend you are not working on, run that frontend yourself from a worktree at main and wire it back at your box:
The shared instance stays untouched; the copy showing your branch’s data is yours alone. Use a separate frontend worktree for each simultaneous backend test setup: tesser dev reuses the box for a worktree and service. In a monorepo, run the dashboard service from the backend change’s worktree. When both dashboard and backend depend on hp, wire both to the hp instance intended for the test. Selecting the dashboard brings all reachable services to localhost, but does not repair inconsistent remote wiring. The agent prepares and verifies the graph; the panel selects it.

Tests that need the dependencies

A workbench has no dependencies of its own, because it does not serve anything. For an integration test that expects localhost:5432 to be a database, borrow a service’s dependencies for the run:
The workbench gets api’s dependency ports for as long as the command runs and releases them afterwards. The ports resolve exactly as they do for api’s own box in this worktree — its wires included — so the test sees what the service sees. --in api on its own only changes the working directory to api’s root.

Names

Service names are shared across the org. api means the same service whether the manifest lives in this repository or another one, which is what lets a dependency declared in one repository reach a service declared in another. Registering a name that another repository already owns is an error.