---
title: "Setup and run scripts"
description: "Automate environment setup and application previews with versioned project commands."
canonical_url: "https://hoplite.sh/docs/sandboxes/scripts"
markdown_url: "https://hoplite.sh/docs/sandboxes/scripts.md"
---

# Setup and run scripts
URL: /docs/sandboxes/scripts
LLM index: /llms.txt
Description: Automate environment setup and application previews with versioned project commands.
Related: /docs/sandboxes, /docs/sandboxes/previews, /docs/sandboxes/environment-variables, /docs/agent/mcp

# Setup and run scripts

Make environment setup and previews repeatable with `.hoplite/settings.json`. Commit the commands your project needs, and Hoplite runs setup in every new thread's sandbox and uses the run script to start the managed preview.

## Configure the file

```json title=".hoplite/settings.json"
{
  "version": 1,
  "ports": {
    "preview": 3000,
    "additional": { "api": 8787 }
  },
  "scripts": {
    "setup": { "enabled": true, "command": "pnpm install && pnpm db:migrate" },
    "run": { "enabled": true, "command": "pnpm dev" },
    "archive": { "enabled": true, "command": "pnpm db:snapshot" }
  }
}
```

Each script is `{ "enabled": boolean, "command": string | null }`. `enabled` defaults to `true`.

| Script | When it runs |
| --- | --- |
| `setup` | After the repo is cloned, in the background while the agent reads the code ([details](#setup-runs-in-the-background)) — install dependencies, run migrations, seed data |
| `run` | When a [preview](/docs/sandboxes/previews) starts — your dev server command |
| `archive` | When a thread is archived — cleanup or state capture |
| `check` | Optional — a verification command (tests, typecheck) the agent can run |

File edits do not automatically execute repository commands. The former `scripts.diagnostics` setting is ignored; ask the agent to run an explicit verification command, such as the project's tests or typecheck, instead.

<Callout type="tip" title="Make scripts self-sufficient">
Scripts run non-interactively in a fresh environment. Anything they need — package manager, language runtime, database — should either be declared in the repo (lockfiles, `.node-version`, etc.) so Hoplite can [provision it](#declared-toolchains), or installed by the setup script itself. Secrets come from your project's [environment variables](/docs/sandboxes/environment-variables).
</Callout>

## Declared toolchains

Before your setup script runs, Hoplite installs the language toolchains your repository declares, in the workspace user's home through mise, so no root access is needed. It reads versions from a mise config or `.tool-versions`, the idiomatic version files (`.nvmrc`, `.node-version`, `.python-version`, `.ruby-version`, `.go-version`, `.java-version`, `.sdkmanrc`), and a bounded `engines.node` range in `package.json`. It also infers toolchains from build files when they're missing from the image:

- A Temurin JDK for `pom.xml` or Gradle builds, using the Java release the build file names, plus Maven or Gradle when the project has no wrapper. A bare Java major such as `21` also resolves to Temurin.
- Go from `go.mod` or `go.work`, Rust from `rust-toolchain.toml`, `rust-toolchain`, or `Cargo.toml`, Ruby from the `Gemfile`, and PHP with Composer from `composer.json`.
- Deno, .NET from `global.json` or project files, and Flutter or Dart from `pubspec.yaml`.
- The Supabase CLI for `supabase/config.toml`, the AWS CLI for SAM, CDK, Serverless, or LocalStack projects, and the Stripe CLI when `package.json` scripts call `stripe`.

Provisioning runs on every setup and is quick when nothing new is declared. It never fails setup by itself; the agent sees which toolchains were installed or failed as setup notes, and your own setup command reports anything that's still missing. On Modal, binaries from `go install`, pipx or `pip --user`, and the Deno installer are on `PATH`, as are the Postgres 16 server tools (`initdb`, `pg_ctl`), and `CHROME_PATH` points at a Chrome binary for Lighthouse, Selenium, and similar tools.

## Ports

`ports.preview` (default `3000`) is the port `preview_start` waits on and proxies. `ports.additional` names extra ports (for example an API server) so they're easy to reference. Port numbers must be between 3000 and 9999.

## How scripts resolve

Projects have a second settings layer in Hoplite itself, editable under **Settings → Project → Environment** — or directly by the agent via `project_control` with `op: "settings_update"`. Resolution order:

1. **Hoplite override** — wins if set, including `enabled: false` to disable a script
2. **Repo file** (`.hoplite/settings.json`) — applies when the override is `null`
3. **Defaults** — `setup`, `run`, and `archive` exist with empty commands if neither layer defines them

The agent's `project_control` tool with `op: "settings_get"` shows which source supplies each active script and whether an override is configured. Private project-override commands are omitted from agent results; repository commands remain inspectable. Review private commands in project settings.

## Setup runs in the background

Every new thread clones the repository and runs the setup script. Setup doesn't hold up the agent: the run starts as soon as the checkout exists, and while setup runs the agent can already read the code with inspection tools, such as listing and reading files and searching the repository. Tools that execute commands or change the workspace become available once setup finishes. If the agent needs them sooner, it waits for setup to finish.

Keep setup fast and repeatable. It runs in every new thread, and the agent can't run tests or start a preview until it finishes.

## Debug a failing script

Ask the agent what resolved: `project_control` with `op: "settings_get"` shows the active source and configuration status without revealing private project-override commands. Failed commands are never replayed automatically, so the agent can inspect the preserved failure and retry deliberately. The one exception is disk exhaustion — after an automatic disk grow, setup retries once, because dependency installation is safe to repeat (see [Resources and scaling](/docs/sandboxes/resources)).

For run-script failures, a crashed preview surfaces the exit reason — including out-of-memory kills — and a redacted, bounded run-log tail. See [Preview your app](/docs/sandboxes/previews).

## MCP servers

Connect [MCP servers](/docs/agent/mcp) in Hoplite's managed project or workspace settings. Hosted runs ignore the repository file's `mcpServers` array, so a checkout cannot add integrations or replace their credentials.

## Sitemap

Sitemap discovery is not enabled for this deployment.
