Skip to content

Startup, teardown, and maintenance

On this page

Use a startup script to install dependencies or start services on each new devbox, and a teardown script to clean up resources when a devbox is destroyed. Template box maintenance serves a different purpose: it updates the saved environment that future devboxes will start from, for example by installing dependencies after a lockfile changes.

A new devbox begins with the files in the project's saved environment — the latest Template box snapshot, or a managed project's current Team Template version. The new-thread branch selection determines which code boxes.dev will prepare before it runs startup commands.

Starting branches

Open the Branch menu below the composer in a new desktop draft to select a remote branch. For a project with several repositories, choose a branch for each one. This is separate from the agent's working directory. You can enter a branch name even if it hasn't appeared in the list yet. Search filters the branch names available on the prepared devbox; it does not search the remote repository as you type.

boxes.dev will fetch and check out those branches before startup scripts run. For a project with configured branch defaults, your choice becomes that project's default after the first message is accepted. Future devboxes use the saved choice across devices, including work started by automations or the CLI. Closing an unsent draft or a failed start won't change the default.

Setup and import show the default branches separately from the startup script. The default determines which code a new devbox will start on; the script contains commands to run after checkout. You can edit the same defaults in Project settings → Devbox lifecycle → New devbox defaults, above the startup commands, then choose Save. In the mobile app, they're under Project settings → Devbox lifecycle → Default branch. Clearing the startup script will keep the branch defaults.

If a project doesn't have a default branch yet, these settings show an empty branch field for each of its repositories. Once you save a branch, new devboxes will fetch it and match its latest commit, discarding uncommitted changes and untracked files that Git doesn't ignore in the Template box's saved files. In a project with several repositories, enter a branch for each one.

For normal setup, choose the repository's remote default branch, usually main, so each new devbox starts with fresh code regardless of the Template box's current branch. Choose another starting branch when your work needs it.

For projects using the standard generated Git startup commands, preparation keeps the same reset behavior: the new devbox's tracked files will match the remote branch, untracked files will be removed, and ignored files will remain. Projects without those generated commands keep their saved checkout until you choose a branch. In those projects, an explicit choice will preserve local work and stop if conflicting edits or unpublished commits prevent the switch. That choice applies to the current draft without saving a project default. Your Template box won't be changed.

Keep dependency installation, environment setup, and service startup in the startup script. boxes.dev handles the generated fetch/checkout commands, so they don't need to run again in the script. Remove custom commands that switch branches or reset Git history. If setup leaves a different branch checked out, boxes.dev will ask you to resolve the conflict before starting the agent.

The selection applies to a new devbox. Starting another thread on an existing devbox or copying an existing conversation will keep that devbox's checkout.

Configure startup and teardown

  1. Open Project settings → Devbox lifecycle → New devbox defaults in the desktop app.
  2. Enter shell commands in Startup script and set its Timeout. The default is 60 seconds; the allowed range is 1–120 seconds.
  3. If the project needs cleanup before a devbox is destroyed, enter those commands in Teardown script. Its timeout defaults to 30 seconds and allows the same 1–120 seconds.
  4. Choose Save. boxes.dev will store the commands as project settings; it will not create script files for you.

Both scripts run in a noninteractive shell. If the project is connected to AWS or Google Cloud, they get the same defaults as a new terminal, so aws and gcloud work without extra setup. In an independent project, they run in the project root. In a managed project, startup runs inside the sole repository, or from the project root when there are zero or several repositories; teardown still runs from the project root. Name a repository folder in commands when needed (cd web && pnpm install). Review any commands that change external services before saving them. Destruction will continue even if teardown fails, so do not rely on teardown as the only way to save important work.

A managed project starts with the Team Template's default startup and teardown scripts; the copies here belong to your project, and editing them changes only your own devboxes. Member devboxes also run the team's own startup and teardown stages, which team admins manage in Maintain a Team Template.

When startup runs

boxes.dev can prepare a new devbox while you type the first prompt and run startup before you press Send. In a managed project, that preparation runs the team script and then your member startup script. A missing required member file or value will block startup until you add it in Project settings.

Make startup scripts safe to repeat: preparation can happen more than once — boxes.dev will discard a prepared devbox and prepare another if the settings change, a branch changes after setup starts, or a draft is abandoned. Before setup starts, branch changes can reuse the same devbox. Send will wait for the selected branches and reuse completed setup. Discarding a devbox does not undo changes the script made to external services; undo those changes yourself when needed.

Managed environment files, project storage, Git access, AWS credentials, and configured outbound networking are prepared before startup. Tailscale connects after Send, so the script should not depend on Tailscale access.

On any one devbox, startup runs once before its first agent turn. Waking it or starting another thread on it will not rerun the scripts.

If a startup command fails or times out, the devbox will still start and the thread will show a warning; inspect the output shown with it and fix the problem before relying on your app. A corrected script will apply to the next devbox — on this one, run the needed commands yourself in Terminal or ask the agent. Dismissing the warning acknowledges that result across your devices; a later failure can still produce a new warning.

When you choose starting branches, checkout must finish and setup must leave the selected branches checked out before the agent starts. If setup changes a branch, fix the startup script and retry preparation. If boxes.dev cannot confirm that a timed-out command stopped, it will keep the draft available to retry.

Maintain your Template box

For an independent project with its own Template box, configure maintenance on the Template box page:

  1. Choose Set up maintenance.
  2. Enter the commands that update your environment and set a timeout of up to eight minutes. The script will run as the boxes user in the project root.
  3. Save the settings, then choose Run now to test them.

If the script succeeds, boxes.dev will save a new snapshot for future devboxes. Keep interactive work off the Template box while a maintenance run is expected: the script will change that machine and may interrupt someone using it.

If your independent project was created from a Team Template that had maintenance configured, it arrived with its own copy of that script and schedule. The copy belongs to your project — manage it here, and later Team Template changes won't update it.

Write the script

A maintenance script should first bring the Template box's code up to date: fetch the latest default branch and fast-forward to it. It should then install locked dependencies and refresh any generated files or tooling, without waiting for input. If the checkout has uncommitted changes or is on another branch, a required value is missing, or an update fails, the script should stop with a clear message and a nonzero exit code. A script that skips its update and still exits successfully will save a stale snapshot. Keep credentials out of the script and read them from managed environment files instead.

The script runs in a noninteractive bash shell with set -e -o pipefail, so any failing command stops it. Commands that your interactive shell sets up in ~/.bashrc, such as nvm, aren't loaded; the script needs to load them itself. If the project is connected to AWS or Google Cloud, the script gets the same defaults as a new terminal and uses your sign-in. A tool that saves an access token to a file during maintenance, such as a package registry login, leaves that token in the snapshot that new devboxes copy, so have the script delete the file before it finishes.

Run maintenance automatically

Choose an optional schedule: every 6 hours, every 12 hours, nightly, or weekly. With GitHub connected, you can also watch files or directories in the project's own repositories. A lockfile watch, for example, can trigger a script that pulls the changed lockfile and installs the updated dependencies — the watch only requests the run, so the script itself has to fetch the change.

Enter exact repository-relative paths, one per line. Watches use each repository's default branch; globs and custom branches are not supported. Maintenance can watch up to ten repositories and fifty total paths.

Adding or editing a watch starts tracking from the repository's current state without immediately running maintenance. After a push, boxes.dev checks whether the watched files have changed; a change reverted before that check will not trigger a run.

Use trigger details in your script

Multi-repository projects use one script and one snapshot per run. For a GitHub-triggered run, your script can read the JSON file named by BOXES_TEMPLATE_MAINTENANCE_CONTEXT_FILE; it lists the triggering repositories, their inspected commits, and the watched paths that changed.

Check the result or recover a failure

boxes.dev keeps the Template box awake until the run and its snapshot finish, so the script can use its full timeout even when nobody is connected.

If the script fails, times out, is canceled, or stops before it finishes, boxes.dev will not take a snapshot. Changes the script already made will remain on the live Template box; inspect them before retrying. When a run stops early, maintenance settings will show the reason and the output captured so far.

The page shows output and recent run history. Cancel run stops a queued or running script; it cannot cancel snapshot creation after a successful script. If only the snapshot failed, use its retry instead of rerunning the script.

From your own computer, run dvb projects maintenance runs --project <project> to inspect active and recent runs, then dvb projects maintenance logs --project <project> --run <run-id> using a listed run ID. An agent on the Template box or one of its devboxes can use dvb-onbox project maintenance runs and logs --run <run-id> once you allow it to edit project settings. Both show recorded script status, exit codes, timestamps, and failure details. History includes up to twenty completed runs; logs contain the combined stdout/stderr tail of up to 4,000 characters. Reading these records will not wake the Template box or start maintenance.

Maintenance and snapshot creation do not run at the same time. If a GitHub watch reports an access problem, follow its reconnect or repository-access instructions. Retry other watch errors and contact support if they persist.

Maintenance notices

For an independent project you own, the desktop workbench shows a banner when Template maintenance needs attention. Choose Maintenance settings to see the failure. For a failed or timed-out script, Ask an agent to fix it will prepare a new thread on the Template box with the saved script and recorded error. Review and send the prompt when you're ready; creating the draft won't start the agent or enable permissions.

Dismiss the banner to hide it for a week on this device. The attention icon on the Template box row will remain until the failure is resolved or acknowledged in maintenance settings.

If the Template has no maintenance script and a default-branch checkout is at least 100 commits behind GitHub, a separate banner recommends pulling the latest changes or adding maintenance. Its agent shortcut will prepare a setup prompt. Checking the commit count won't wake the Template box. After you dismiss this reminder, it can return only after a week and another 100 commits of lag. These reminders are saved separately for your account on each device; Team Template projects use their admin maintenance workflow instead.

Team Template maintenance

A Team Template — the shared starting environment a team admin maintains — has its own maintenance workflow: it updates the team's clean saved environment and publishes a verified saved version. Managed projects do not run Template box maintenance of their own. Team admins manage all of this in Maintain a Team Template.

Ask an agent to configure scripts

You can also ask an agent in your independent project to edit startup and teardown scripts and maintenance watches. It can work from the Template box or any devbox. The agent will ask for permission to edit project settings; choose Allow for 3 hours to let that thread make the change. The agent can also start a maintenance run and check its result, so it can confirm that a corrected script works and that the new snapshot was saved.

On a Template box where Edit devbox lifecycle or Edit template maintenance is already on in Agent permissions, its agents can make those changes without asking. To schedule an agent conversation instead of a shell script, use an automation.