> ## Documentation Index
> Fetch the complete documentation index at: https://docs.boxd.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

> From zero to a live machine on the internet in under a minute.

<Note color="#E05A6D">
  If you're an AI agent reading this, fetch [llms.txt](https://docs.boxd.sh/llms.txt) or [llms-full.txt](https://docs.boxd.sh/llms-full.txt) instead. They're built for you.
</Note>

## 1. Install

One command, before anything else:

```bash theme={"theme":"github-dark"}
curl -fsSL https://boxd.sh/downloads/install.sh | sh
```

Gets you the `boxd` CLI and the `<vm>.boxd` SSH aliases. The [client utilities](/reference/client-utilities) (clipboard, files, and browser into every VM) are built in too — turn them on with `boxd client enable`.

Then pick your client:

<Tabs sync={false}>
  <Tab title="SSH">
    Nothing to install — your SSH key is already linked. Drive the control plane straight from your terminal:

    ```bash theme={"theme":"github-dark"}
    ssh boxd.sh
    ```
  </Tab>

  <Tab title="CLI">
    Sign in with GitHub, then the `boxd` command is ready:

    ```bash theme={"theme":"github-dark"}
    boxd login
    ```
  </Tab>

  <Tab title="TypeScript">
    Add the SDK and mint a key:

    ```bash theme={"theme":"github-dark"}
    npm install @boxd-sh/sdk
    export BOXD_API_KEY=$(boxd keys create my-app)
    ```
  </Tab>

  <Tab title="Python">
    Add the SDK and mint a key:

    ```bash theme={"theme":"github-dark"}
    pip install boxd
    export BOXD_API_KEY=$(boxd keys create my-app)
    ```
  </Tab>
</Tabs>

## 2. Create a machine

<Tabs sync={false}>
  <Tab title="SSH">
    ```bash theme={"theme":"github-dark"}
    ssh boxd.sh new --name=myapp
    ```

    Running a bunch of commands in a row? Drop into the REPL with just `ssh boxd.sh` (no args) and run them without the prefix:

    ```bash theme={"theme":"github-dark"}
    $ ssh boxd.sh
    boxd> new --name=myapp
    boxd> fork myapp --name=myapp-test
    boxd> list
    boxd> exit
    ```
  </Tab>

  <Tab title="CLI">
    ```bash theme={"theme":"github-dark"}
    boxd new --name=myapp
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript theme={"theme":"github-dark"}
    import { Compute } from "@boxd-sh/sdk";

    const c = new Compute();                              // reads BOXD_API_KEY
    const box = await c.box.create({ name: "myapp" });
    console.log(box.url, box.bootTimeMs);
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={"theme":"github-dark"}
    from boxd import Compute

    c = Compute()                              # reads BOXD_API_KEY
    box = c.box.create(name="myapp")
    print(box.url, box.boot_time_ms)
    ```
  </Tab>
</Tabs>

You'll see:

```text theme={"theme":"github-dark"}
    name: myapp
      id: 9645b1e8-193d-4d11-86b1-f91deff5bbfb
     url: myapp.boxd.sh
    boot: 30ms

Connect via SSH: ssh myapp.boxd
Or from your browser: https://myapp.boxd.sh
```

The machine has a persistent disk and its own HTTPS domain. TLS is already terminated. Visit the URL. You'll see a default landing page until you start a server.

<Note>
  From the SDKs, give the VM a couple of seconds before the first `exec`. `create` and `fork` return as soon as the VM is scheduled; the in-VM exec endpoint takes another second or two to accept connections. The SSH and CLI paths handle the wait for you.
</Note>

## 3. Get into the box

<Tabs sync={false}>
  <Tab title="SSH">
    The [install in step 1](#1-install) wrote the `myapp.boxd` alias into your SSH config. SSH straight to the machine by name:

    ```bash theme={"theme":"github-dark"}
    ssh myapp.boxd
    ```

    A real shell as `boxd` (passwordless sudo) — plus `scp`, `rsync`, `ssh -L`, and editor Remote-SSH.

    | Command          | What it is                                             |
    | ---------------- | ------------------------------------------------------ |
    | `ssh myapp.boxd` | the **machine** — a shell inside your VM               |
    | `ssh boxd.sh`    | the **control plane** — create / list / fork / destroy |

    <Accordion title="Drove the control plane over plain SSH instead?">
      No SSH config, no alias — shell in through the control plane:

      ```bash theme={"theme":"github-dark"}
      ssh -t boxd.sh connect myapp
      ```

      From code, drive the box with `exec` rather than shelling in.
    </Accordion>
  </Tab>

  <Tab title="CLI">
    ```bash theme={"theme":"github-dark"}
    boxd connect myapp
    ```

    Drops you straight into an interactive shell on the machine over the boxd API — no SSH config, no host keys. Auto-resumes paused or hibernated machines. Type `exit` or Ctrl-D to come back to your local shell.
  </Tab>
</Tabs>

## 4. Make it live

nginx is pre-installed on port 8000 (the default proxy port). Start it:

<Tabs sync={false}>
  <Tab title="SSH">
    ```bash theme={"theme":"github-dark"}
    ssh boxd.sh exec myapp -- sudo systemctl start nginx
    ```

    Already in the `boxd>` REPL? Just:

    ```bash theme={"theme":"github-dark"}
    exec myapp -- sudo systemctl start nginx
    ```
  </Tab>

  <Tab title="CLI">
    ```bash theme={"theme":"github-dark"}
    boxd exec myapp -- sudo systemctl start nginx
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript theme={"theme":"github-dark"}
    await box.exec(["sudo", "systemctl", "start", "nginx"]);
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={"theme":"github-dark"}
    box.exec("sudo", "systemctl", "start", "nginx")
    ```
  </Tab>
</Tabs>

Refresh `https://myapp.boxd.sh`. Your machine is live on the internet.

## 5. Forking

<Tabs sync={false}>
  <Tab title="SSH">
    ```bash theme={"theme":"github-dark"}
    ssh boxd.sh fork myapp --name=myapp-test
    ```

    Already in the `boxd>` REPL? Just:

    ```bash theme={"theme":"github-dark"}
    fork myapp --name=myapp-test
    ```
  </Tab>

  <Tab title="CLI">
    ```bash theme={"theme":"github-dark"}
    boxd fork myapp --name=myapp-test
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript theme={"theme":"github-dark"}
    const fork = await c.box.fork("myapp", { name: "myapp-test" });
    console.log(fork.url);   // myapp-test.boxd.sh
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={"theme":"github-dark"}
    fork = c.box.fork("myapp", name="myapp-test")
    print(fork.url)   # myapp-test.boxd.sh
    ```
  </Tab>
</Tabs>

\~160ms for a full disk copy. The fork has its own HTTPS domain and a complete snapshot of `myapp` at the moment of the fork. **Running processes come with it.** If `myapp` had a Python server listening on port 8000, the fork is already serving on `https://myapp-test.boxd.sh` the instant it boots. Run experiments on `myapp-test`; the original is untouched. Get into the fork the same way: `ssh myapp-test.boxd`.

## 6. Talk between VMs

Every boxd VM ships the same `boxd` CLI inside. From within either machine you can see, exec into, and copy files between any of your own VMs. No keys, no tokens — auth is automatic by source IP.

```bash theme={"theme":"github-dark"}
ssh myapp.boxd
# inside myapp:
boxd list                                  # see myapp and myapp-test
boxd exec myapp-test 'hostname'            # run a command on the fork
boxd cp ./file myapp-test:/tmp/file        # copy something across
```

The in-VM path is what makes fleets of agents practical — an agent on one VM spawning, exec'ing into, and tearing down siblings without a credential to manage. Full mechanics: [VM-to-VM networking](/how-it-works/vm-to-vm).

When you're done with the fork:

<Tabs sync={false}>
  <Tab title="SSH">
    ```bash theme={"theme":"github-dark"}
    ssh boxd.sh destroy myapp-test -y
    ```
  </Tab>

  <Tab title="CLI">
    ```bash theme={"theme":"github-dark"}
    boxd destroy myapp-test -y
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript theme={"theme":"github-dark"}
    await fork.destroy();
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={"theme":"github-dark"}
    fork.destroy()
    ```
  </Tab>
</Tabs>

## What's next

<Columns cols={2}>
  <Card title="Boot a fresh box" icon="https://mintcdn.com/azin/Ax1V0serIwQf0x_2/images/icons/cloud-bolt.svg?fit=max&auto=format&n=Ax1V0serIwQf0x_2&q=85&s=4a71042864146228fd22daec028c1297" href="/cloud-dev-boxes/boot-a-fresh-box" width="16" height="16" data-path="images/icons/cloud-bolt.svg">
    All the ways to spin up a VM and configure it.
  </Card>

  <Card title="Fork from a golden" icon="https://mintcdn.com/azin/Ax1V0serIwQf0x_2/images/icons/copy.svg?fit=max&auto=format&n=Ax1V0serIwQf0x_2&q=85&s=f3623fe516eebf87b33b3a1022852286" href="/cloud-dev-boxes/fork-from-a-golden" width="16" height="16" data-path="images/icons/copy.svg">
    Pre-warm an app, fork it on demand, destroy when done.
  </Card>

  <Card title="Per-PR preview URLs" icon="https://mintcdn.com/azin/Ax1V0serIwQf0x_2/images/icons/branching-paths-up.svg?fit=max&auto=format&n=Ax1V0serIwQf0x_2&q=85&s=06ff61ff2b80a7adc15558368629f9bb" href="/preview-environments/per-pr-preview-urls" width="16" height="16" data-path="images/icons/branching-paths-up.svg">
    A boxd URL on every pull request.
  </Card>

  <Card title="Agent sandboxes" icon="https://mintcdn.com/azin/Ax1V0serIwQf0x_2/images/icons/robot.svg?fit=max&auto=format&n=Ax1V0serIwQf0x_2&q=85&s=e91e744c2d3cd5da053167486b6834bf" href="/agents/agent-sandboxes" width="16" height="16" data-path="images/icons/robot.svg">
    Give your agent its own real computer.
  </Card>
</Columns>
