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

# Creating Devboxes

> Machine sizes, images, repositories, ephemeral Devboxes, and the workspace defaults applied to every new Devbox.

export const KeepTabPosition = () => {
  useEffect(() => {
    const stateKey = "__namespaceKeepTabPosition";
    const releaseState = state => {
      state.instances -= 1;
      if (state.instances > 0) return;
      state.removeListeners();
      if (window[stateKey] === state) delete window[stateKey];
    };
    const existingState = window[stateKey];
    if (existingState) {
      existingState.instances += 1;
      return () => releaseState(existingState);
    }
    const maxSettleTime = 250;
    const requiredStableFrames = 3;
    const positionTolerance = 0.5;
    let animationFrame;
    let observer;
    let settleDeadline;
    let stableFrames = 0;
    let tabListToKeep;
    let tabListTop;
    const findTab = event => {
      if (!(event.target instanceof Element)) return null;
      return event.target.closest(".tab-container [role='tab']");
    };
    const findScrollContainer = element => {
      for (let parent = element.parentElement; parent; parent = parent.parentElement) {
        const {overflowY} = getComputedStyle(parent);
        if ((overflowY === "auto" || overflowY === "scroll") && parent.scrollHeight > parent.clientHeight) {
          return parent;
        }
      }
      return null;
    };
    const stopKeepingPosition = () => {
      if (animationFrame) cancelAnimationFrame(animationFrame);
      animationFrame = undefined;
      observer?.disconnect();
      tabListToKeep = undefined;
    };
    const restoreTabListPosition = () => {
      if (!tabListToKeep?.isConnected) return 0;
      const offset = tabListToKeep.getBoundingClientRect().top - tabListTop;
      if (Math.abs(offset) < positionTolerance) return offset;
      const scrollOptions = {
        top: offset,
        behavior: "instant"
      };
      const scrollContainer = findScrollContainer(tabListToKeep);
      if (scrollContainer) {
        scrollContainer.scrollBy(scrollOptions);
      } else {
        window.scrollBy(scrollOptions);
      }
      return offset;
    };
    const settlePosition = () => {
      const offset = restoreTabListPosition();
      stableFrames = Math.abs(offset) < positionTolerance ? stableFrames + 1 : 0;
      if (stableFrames >= requiredStableFrames || performance.now() >= settleDeadline) {
        stopKeepingPosition();
        return;
      }
      animationFrame = requestAnimationFrame(settlePosition);
    };
    observer = new MutationObserver(() => {
      stableFrames = 0;
      restoreTabListPosition();
    });
    const keepTabListInPlace = tab => {
      stopKeepingPosition();
      tabListToKeep = tab.closest("[role='tablist']");
      if (!tabListToKeep) return;
      tabListTop = tabListToKeep.getBoundingClientRect().top;
      settleDeadline = performance.now() + maxSettleTime;
      stableFrames = 0;
      observer.observe(document.getElementById("content") ?? document.documentElement, {
        attributes: true,
        attributeFilter: ["aria-selected", "class"],
        childList: true,
        subtree: true
      });
      animationFrame = requestAnimationFrame(settlePosition);
    };
    const selectWithoutNavigation = event => {
      if (!event.isTrusted) return;
      const tab = findTab(event);
      if (!tab) return;
      keepTabListInPlace(tab);
      event.preventDefault();
      event.stopPropagation();
      tab.click();
      restoreTabListPosition();
    };
    const selectWithKeyboard = event => {
      if (!event.isTrusted) return;
      const tab = findTab(event);
      const tabList = tab?.closest("[role='tablist']");
      if (!tab || !tabList) return;
      const tabs = Array.from(tabList.querySelectorAll(":scope > [role='tab']"));
      const currentIndex = tabs.indexOf(tab);
      let nextIndex;
      switch (event.key) {
        case "ArrowLeft":
          nextIndex = (currentIndex - 1 + tabs.length) % tabs.length;
          break;
        case "ArrowRight":
          nextIndex = (currentIndex + 1) % tabs.length;
          break;
        case "Home":
          nextIndex = 0;
          break;
        case "End":
          nextIndex = tabs.length - 1;
          break;
        case "Enter":
        case " ":
          nextIndex = currentIndex;
          break;
        default:
          return;
      }
      keepTabListInPlace(tab);
      event.preventDefault();
      event.stopPropagation();
      tabs[nextIndex]?.click();
      tabs[nextIndex]?.focus({
        preventScroll: true
      });
      restoreTabListPosition();
    };
    document.addEventListener("click", selectWithoutNavigation, true);
    document.addEventListener("keydown", selectWithKeyboard, true);
    const state = {
      instances: 1,
      removeListeners: () => {
        stopKeepingPosition();
        document.removeEventListener("click", selectWithoutNavigation, true);
        document.removeEventListener("keydown", selectWithKeyboard, true);
      }
    };
    window[stateKey] = state;
    return () => releaseState(state);
  }, []);
  return null;
};

export const CenteredImage = ({src, alt, width, caption, className}) => {
  const [basePath, setBasePath] = useState("");
  useEffect(() => {
    const path = window.location.pathname;
    setBasePath(path === "/docs" || path.startsWith("/docs/") ? "/docs" : "");
  }, []);
  return <Frame caption={caption} className={className} style={{
    maxWidth: width,
    marginInline: "auto"
  }}>
			<OptimizedImage src={`${basePath}${src}`} alt={alt} />
		</Frame>;
};

<KeepTabPosition />

Everything you choose when a Devbox is created: how big it is, what image it runs, which repository it checks out, and how long it lives. For the full flag set, see [`devbox create`](/docs/reference/devbox-cli/create).

## Creating a Devbox

Give the Devbox a name, an image, and a size. Anything you leave out falls back to a [workspace default](#workspace-defaults).

<Tabs>
  <Tab title="CLI">
    Run `devbox create` with no arguments to be prompted for each value:

    ```bash theme={null}
    devbox create
    ```

    Or pass them inline to skip the prompts:

    ```bash theme={null}
    devbox create --name my-devbox --size m --image builtin:agents --checkout github.com/your-org/your-repo
    ```
  </Tab>

  <Tab title="TS SDK">
    `devboxes.create()` provisions the Devbox and waits for it to become ready:

    ```typescript theme={null}
    const devbox = await client.devboxes.create({
      name: "my-devbox",
      imageName: "builtin:agents",
      size: "m",
      repository: "github.com/your-org/your-repo",
    });
    ```

    See [Create and manage Devboxes](/docs/reference/typescript-sdk/devboxes) for every input field.
  </Tab>

  <Tab title="Dashboard">
    Press **+ Create** on the [Devboxes page](https://cloud.namespace.so/workspace/devboxes). The dialog arrives pre-filled with a generated name, a default image, and a default size, so you can press **Create Devbox** right away, or use the controls to pick a repository, size, and image first.

    <CenteredImage width={700} alt="The New devbox dialog with the repository list expanded" src="/docs/images/devboxes/devbox-create-2.webp" />
  </Tab>
</Tabs>

### Create a macOS Devbox

Ask for macOS instead of the default Linux.

<Tabs>
  <Tab title="CLI">
    ```bash theme={null}
    devbox create --platform macos
    ```

    `--platform` also accepts `macos/arm64`, `linux`, and `linux/amd64`.
  </Tab>

  <Tab title="TS SDK">
    ```typescript theme={null}
    const devbox = await client.devboxes.create({
      name: "my-mac-devbox",
      os: "macos",
      size: "m",
    });
    ```

    macOS creation cannot set `image` or `imageName`.
  </Tab>

  <Tab title="Dashboard">
    Select **macOS** in the toggle at the top of the New devbox dialog, then choose the macOS version and size.

    <CenteredImage width={700} alt="The New devbox dialog with macOS selected and the version list open" src="/docs/images/devboxes/creating/devbox-create-macos.webp" />
  </Tab>
</Tabs>

macOS Devboxes run on Apple Silicon from a Namespace-managed base image, so you choose a macOS and Xcode version rather than supplying your own. They support the **M** and **L** sizes only, and cannot use [custom images](/docs/devbox/images) or nested virtualization.

### Create from a blueprint

Create a Devbox from a saved Blueprint definition.

<Tabs>
  <Tab title="CLI">
    ```bash theme={null}
    devbox create --blueprint my-blueprint
    ```

    `--blueprint` uses the latest version of the named Blueprint, and cannot be combined with `--from` or `--platform`.
  </Tab>

  <Tab title="TS SDK">
    ```typescript theme={null}
    const devbox = await client.devboxes.create({
      name: "my-devbox",
      blueprint: "my-blueprint",
    });
    ```
  </Tab>

  <Tab title="Dashboard">
    On the [Blueprints page](https://cloud.namespace.so/workspace/devboxes/blueprints), click the `...` icon next to a Blueprint, select **Create Devbox**, give it a name, and press **Create Devbox**.

    <CenteredImage width={700} alt="The Blueprints page with the Create Devbox action open on a Blueprint" src="/docs/images/devboxes/creating/devbox-create-from-blueprint.webp" />
  </Tab>
</Tabs>

A Blueprint captures the operating system, base image, machine size, access mode, and optional settings such as repositories, environment variables, and network policy. See [Devbox Blueprints](/docs/devbox/blueprint) to create and configure one.

### Create from a spec file

Declare the configuration in a file, then create from it non-interactively:

```yaml devbox.yaml theme={null}
name: my-devbox
image: builtin:agents
size: m
repository: github.com/your-org/your-repo
```

```bash theme={null}
devbox create --from devbox.yaml
```

See the [spec file reference](/docs/reference/devbox-cli/spec-file) for every field, the supported formats, and how to read a spec from stdin.

## Configuration Options

Set these when you create a Devbox, in any of the forms above.

### Image

Choose the image the Devbox starts from.

<Tabs>
  <Tab title="CLI">
    ```bash theme={null}
    devbox create --image builtin:agents
    ```

    List the images your workspace can use. Both Linux and macOS images are shown:

    ```bash theme={null}
    devbox image list
    ```

    Filter with `--platform linux` or `--platform macos`. To create from a macOS image, pass the platform and the image name together:

    ```bash theme={null}
    devbox create --platform macos --image tahoe
    ```

    <Tip>`--image` follows the latest build of a named image. To pin one exact build, see [Pin an exact image](#pin-an-exact-image).</Tip>
  </Tab>

  <Tab title="TS SDK">
    ```typescript theme={null}
    const devbox = await client.devboxes.create({
      name: "my-devbox",
      imageName: "builtin:agents",
    });
    ```

    `imageName` selects a built-in or registered image by name. Use `image` for a full image reference. Call `client.images.list()` to see what is available.
  </Tab>

  <Tab title="Dashboard">
    Press the image control in the create dialog and choose an image.

    <CenteredImage width={700} alt="The New devbox dialog with the image list open" src="/docs/images/devboxes/creating/devbox-create-macos-images.webp" />
  </Tab>
</Tabs>

macOS images are Namespace-managed and named after their release, such as `tahoe` or `sequoia`, and each bundles a macOS and Xcode version. Only Linux Devboxes can use images you build yourself.

To bake your own tools and runtimes into an image, see [Custom Images](/docs/devbox/images).

### Machine Size

Choose how much CPU and memory the Devbox gets.

<Tabs>
  <Tab title="CLI">
    ```bash theme={null}
    devbox create --size m
    ```
  </Tab>

  <Tab title="TS SDK">
    ```typescript theme={null}
    const devbox = await client.devboxes.create({
      name: "my-devbox",
      imageName: "builtin:agents",
      size: "m",
    });
    ```
  </Tab>

  <Tab title="Dashboard">
    Press the size control in the create dialog and choose a size.

    <CenteredImage width={700} alt="The New devbox dialog with the machine size list open" src="/docs/images/devboxes/creating/devbox-create-size.webp" />
  </Tab>
</Tabs>

The available sizes differ between Linux and macOS.

<Tabs>
  <Tab title="Linux" icon="https://mintcdn.com/namespace-labs/RAfpS6JkeZq1maU3/images/icons/linux.svg?fit=max&auto=format&n=RAfpS6JkeZq1maU3&q=85&s=5442034c78f9da6d7b50cbdc5a915f3a" width="24" height="24" data-path="images/icons/linux.svg">
    | Size   | CPU              | Memory |
    | ------ | ---------------- | ------ |
    | **S**  | Burst to 4 vCPU  | 8 GB   |
    | **M**  | Burst to 8 vCPU  | 16 GB  |
    | **L**  | Burst to 16 vCPU | 32 GB  |
    | **XL** | Burst to 32 vCPU | 64 GB  |

    Linux vCPU counts represent burstable capacity.
  </Tab>

  <Tab title="macOS" icon="https://mintcdn.com/namespace-labs/YnODJWPvsMShiQQC/images/icons/apple.svg?fit=max&auto=format&n=YnODJWPvsMShiQQC&q=85&s=1076263ef0a75ced2146cc606bb3871b" width="24" height="24" data-path="images/icons/apple.svg">
    | Size  | CPU     | Memory |
    | ----- | ------- | ------ |
    | **M** | 6 vCPU  | 14 GB  |
    | **L** | 12 vCPU | 28 GB  |

    macOS supports the **M** and **L** sizes only.
  </Tab>
</Tabs>

<Info>Your workspace policy may restrict which sizes are available.</Info>

### Repository

Clone a repository into the Devbox when it is created. This requires a [connected GitHub organization](/docs/devbox#getting-started).

<Tabs>
  <Tab title="CLI">
    ```bash theme={null}
    devbox create --checkout github.com/your-org/your-repo
    ```

    Omitting `--checkout` applies the workspace default repository. Pass `--no_checkout` to skip the checkout entirely.
  </Tab>

  <Tab title="TS SDK">
    ```typescript theme={null}
    const devbox = await client.devboxes.create({
      name: "my-devbox",
      imageName: "builtin:agents",
      repository: "github.com/your-org/your-repo",
    });
    ```
  </Tab>

  <Tab title="Dashboard">
    Press **Repository** in the create dialog and select the repository to check out.

    <CenteredImage width={700} alt="The New devbox dialog with the repository list expanded" src="/docs/images/devboxes/devbox-create-2.webp" />
  </Tab>
</Tabs>

To pin a branch, tag, or commit, use the `repository` block in a [spec file](/docs/reference/devbox-cli/spec-file#repository).

### Access Mode

Choose whether the Devbox is private to you or shared with the workspace. When omitted, the workspace default applies.

<Tabs>
  <Tab title="CLI">
    ```bash theme={null}
    devbox create --access_mode shared
    ```

    `--access_mode` accepts `private` or `shared`.
  </Tab>

  <Tab title="TS SDK">
    ```typescript theme={null}
    const devbox = await client.devboxes.create({
      name: "my-devbox",
      imageName: "builtin:agents",
      access: "workspace",
    });
    ```

    `access` accepts `private` or `workspace`.
  </Tab>

  <Tab title="Dashboard">
    Expand the **Advanced** section in the create dialog and set the access mode.

    <CenteredImage width={700} alt="The Advanced section of the New devbox dialog with the access mode list open" src="/docs/images/devboxes/creating/devbox-create-access-mode.webp" />
  </Tab>
</Tabs>

### Idle Timeout

Control how long a Devbox stays running after it goes idle. The dashboard offers presets of 15 minutes, 30 minutes, 1 hour, 4 hours, and 8 hours, plus a custom value. The CLI accepts any duration.

<Tabs>
  <Tab title="CLI">
    ```bash theme={null}
    devbox create --auto_stop_idle_timeout=1h
    ```
  </Tab>

  <Tab title="Dashboard">
    Expand the **Advanced** section in the create dialog to configure the idle timeout.

    <CenteredImage width={700} alt="The Advanced section of the New devbox dialog with the idle timeout list open" src="/docs/images/devboxes/creating/devbox-create-idle-timeout.webp" />
  </Tab>
</Tabs>

See [Idleness and auto-stop](/docs/devbox/lifecycle#idleness--auto-stop) for how idleness is detected, and [Running long tasks](/docs/guides/devbox/long-running-tasks) to learn how to keep a Devbox alive for long-running tasks.

### Volume Size

Persistent storage defaults to the workspace setting. Override it when a repository or build cache needs more room:

<Tabs>
  <Tab title="CLI">
    ```bash theme={null}
    devbox create --volume_size_gb=300
    ```
  </Tab>

  <Tab title="TS SDK">
    ```typescript theme={null}
    const devbox = await client.devboxes.create({
      name: "my-devbox",
      imageName: "builtin:agents",
      volumeSizeGB: 300,
    });
    ```
  </Tab>

  <Tab title="Dashboard">
    Expand the **Advanced** section in the create dialog to set the volume size.

    <CenteredImage width={700} alt="The Advanced section of the New devbox dialog with the volume size list open" src="/docs/images/devboxes/creating/devbox-create-volume-size.webp" />
  </Tab>
</Tabs>

### Ephemeral

Create a Devbox whose instance and storage are deleted when it stops.

<Tabs>
  <Tab title="CLI">
    ```bash theme={null}
    devbox create --ephemeral
    ```
  </Tab>

  <Tab title="TS SDK">
    ```typescript theme={null}
    const devbox = await client.devboxes.create({
      name: "throwaway",
      imageName: "builtin:agents",
      ephemeral: true,
    });
    ```

    Pass an object instead of `true` to control how long the stopped Devbox is retained.
  </Tab>
</Tabs>

Ephemeral Devboxes start fresh every time. They suit short-lived tasks or experimentation where you don't need to keep data across restarts.

### Site

Pin the Devbox to a specific site. By default it is created in the site closest to you.

<Tabs>
  <Tab title="CLI">
    ```bash theme={null}
    devbox create --site iad
    ```

    To list the available sites with their measured latencies, run [`devbox site-latency`](/docs/reference/devbox-cli/site-latency):

    ```bash theme={null}
    devbox site-latency
    ```

    It reports p50 and p90 for each site and highlights the closest one.
  </Tab>

  <Tab title="TS SDK">
    ```typescript theme={null}
    const devbox = await client.devboxes.create({
      name: "my-devbox",
      imageName: "builtin:agents",
      site: "iad",
    });
    ```
  </Tab>
</Tabs>

## Workspace Defaults

Workspace admins can set default values applied to all newly created Devboxes. Navigate to the [Defaults page](https://cloud.namespace.so/workspace/devboxes/defaults) in the dashboard to configure:

<CenteredImage width={600} alt="The workspace Defaults page showing image, size, volume, repository, access mode, idle timeout, network, and integration defaults" src="/docs/images/devboxes/creating/devbox-defaults.webp" />

* **Image**: default base image, which also determines the operating system (Linux or macOS)
* **Instance size**: default CPU and memory allocation
* **Volume size**: default persistent volume size for new Devboxes
* **Git repository**: default repository to clone
* **Access mode**: private (just you) or workspace-wide (shared with all members)
* **Auto-stop timeout on idle**: how long Devboxes stay running when idle

**Network**

* **Egress policy**: default outbound network access restrictions

**Integrations**

* **Bazel**: enable [Bazel integration](/docs/integrations/bazel) to share Bazel cache across Devboxes
* **Tailscale**: default [Tailscale integration spec](/docs/integrations/tailscale) to connect Devboxes to your tailnet

When a workspace policy is active, policy-enforced values take precedence and are shown as locked in the UI.

<h2 id="pin-an-exact-image">
  Pin an exact image
</h2>

`--image` follows the latest build of a named image, so a Devbox created today and one created next month can differ. To pin a single build that never changes, pass a full registry reference to `--image_ref` instead.

List the images with their references:

```bash theme={null}
devbox beta image list --output json
```

```json Output nocopy theme={null}
{
  "name": "builtin:base",
  "os": "linux",
  "description": "Default image",
  "linux": {
    "image_ref": "public.registry.namespace.systems/namespacelabs.dev/internal/devbox/userimages/base@sha256:8df5e479...",
    "repository": "public.registry.namespace.systems/namespacelabs.dev/internal/devbox/userimages/base",
    "digest": "sha256:8df5e479..."
  }
}
```

Pass the `image_ref` value to `devbox create`:

```bash theme={null}
devbox create --image_ref <repository>@sha256:<digest>
```

`--image` and `--image_ref` are mutually exclusive. `--image_ref` applies to Linux images only: macOS Devboxes must use `--image` with a macOS image name.

<h2 id="github-cli-authentication">
  GitHub CLI Authentication
</h2>

Forward your local `gh` CLI authentication to a Devbox so `gh` commands and HTTPS git operations are authenticated. Do it at creation time, or against a Devbox that already exists:

<Tabs>
  <Tab title="At creation">
    ```bash theme={null}
    devbox create --setup_github
    ```
  </Tab>

  <Tab title="Existing Devbox">
    ```bash theme={null}
    devbox setup-github my-devbox
    ```

    See [`devbox setup-github`](/docs/reference/devbox-cli/setup-github) for what the command does on the Devbox.
  </Tab>

  <Tab title="Spec file">
    ```yaml devbox.yaml theme={null}
    name: my-devbox
    image: builtin:agents
    size: m
    integrations:
      github:
        share_auth: true
    ```
  </Tab>
</Tabs>

The local `gh` token is read before the Devbox is created, so a missing or expired login fails fast. When both are given, the `--setup_github` flag overrides the spec value.

## Next Steps

<Columns cols={3}>
  <Card title="Devbox Lifecycle" icon="refresh-cw" href="/docs/devbox/lifecycle">
    Listing, starting, stopping, idleness, and deleting.
  </Card>

  <Card title="Sessions" icon="square-terminal" href="/docs/devbox/sessions">
    Persistent terminal sessions that survive disconnections.
  </Card>

  <Card title="Blueprints" icon="layers" href="/docs/devbox/blueprint">
    Reusable Devbox configurations to create from.
  </Card>
</Columns>
