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

# Templates

> Built-in templates for common workloads, plus how to build your own with pre-installed dependencies.

A template is the rootfs image used when a sandbox boots. Declaw ships a small
set of curated built-in templates for the most common workloads, and you can
build your own when you need a different runtime, custom packages, or
project files baked in.

If you don't pass `template`, sandboxes use **`base`** — a minimal `Ubuntu 22.04` image with shell utilities only.

## Built-in templates

| Template   | What's preinstalled                                                                                           | Use it for                                                    |
| ---------- | ------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- |
| `base`     | `Ubuntu 22.04`, `git`, `curl`, `wget`, `jq`, `build-essential`                                                | Shell-only workflows, custom toolchains                       |
| `python`   | `base` + `Python 3.10`, `pip`, `numpy`, `pandas`, `requests`, `httpx`, `pydantic`                             | Python scripts, data processing, REST clients                 |
| `node`     | `base` + `Node.js 20 LTS`, `npm`, `typescript`, `yarn`                                                        | TypeScript / Node scripts, npm packages                       |
| `ai-agent` | `base` + `Python 3.10` + `Node.js 20` + LLM/agent SDKs ([full list](/cookbook/templates/ai-agent-frameworks)) | Agent workloads — LangChain, CrewAI, AutoGen, LlamaIndex, MCP |

<Note>
  Built-in templates are versioned with the platform — you don't need to build
  them. They are referenced by name (`template="python"`, etc.) and pull a
  pre-published rootfs image from the Declaw blob store.
</Note>

### How to choose

* Need to run a one-off shell command or your own statically-linked binary? → `base`
* Running Python code, especially with `requests` / `pandas` / `numpy`? → `python`
* Running a TypeScript or Node.js script? → `node`
* Running an LLM-driven agent (LangChain, CrewAI, AutoGen, LlamaIndex, OpenAI Agents, MCP)? → `ai-agent`

If your workload needs something not in the list above (a different language
runtime, a heavy ML framework like `torch`, project files baked in, etc.) —
build a custom template. See [Build a custom template](#build-a-custom-template)
below.

### Worked examples

Each built-in template has a runnable cookbook example you can copy:

<CardGroup cols={2}>
  <Card title="base — shell tools" icon="terminal" href="/cookbook/templates/base-shell-tools">
    Run `git`, `curl`, and `jq` end-to-end inside a fresh sandbox.
  </Card>

  <Card title="python — pandas analysis" icon="python" href="/cookbook/templates/python-pandas-analysis">
    Pipe a CSV through `pandas` and read back JSON results.
  </Card>

  <Card title="node — TypeScript script" icon="js" href="/cookbook/templates/node-typescript-script">
    Compile a `.ts` file with `tsc` and run the output with `Node.js 20`.
  </Card>

  <Card title="ai-agent — frameworks check" icon="robot" href="/cookbook/templates/ai-agent-frameworks">
    Boot an agent sandbox and verify the major LLM-framework SDKs import.
  </Card>

  <Card title="ai-agent — KYC with CrewAI" icon="shield-check" href="/cookbook/templates/ai-agent-kyc-crewai">
    Fintech: four-agent CrewAI KYC pipeline with PII + injection defense.
  </Card>

  <Card title="ai-agent — prior auth with LangGraph" icon="file-medical" href="/cookbook/templates/ai-agent-prior-auth-langgraph">
    Health-tech: LangGraph workflow with PHI redact + rehydrate around GPT-4.1.
  </Card>
</CardGroup>

## Build a custom template

Use `Template.build()` when none of the built-ins fit — most commonly when
you need additional Python packages, project files copied in, or a different
base image.

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    from declaw import Template

    template = Template.build(
        template="""
    FROM ubuntu:22.04
    RUN apt-get update && apt-get install -y python3 python3-pip
    RUN pip3 install numpy pandas scikit-learn matplotlib
    WORKDIR /workspace
    """,
        alias="data-science",
    )
    print(template.template_id)  # tpl-abc123
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript theme={null}
    import { Template } from '@declaw/sdk';

    const template = await Template.build({
      template: `
    FROM ubuntu:22.04
    RUN apt-get update && apt-get install -y python3 python3-pip
    RUN pip3 install numpy pandas scikit-learn matplotlib
    `,
      alias: 'data-science',
    });
    console.log(template.templateId);
    ```
  </Tab>
</Tabs>

### Build with options

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    template = Template.build(
        template="""
    FROM ubuntu:22.04
    RUN pip3 install anthropic openai langchain
    COPY ./prompts /workspace/prompts
    """,
        alias="llm-agent",
        cpu_count=2,
        memory_mb=1024,
        on_build_logs=lambda line: print(line),  # stream build output
    )
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript theme={null}
    const template = await Template.build({
      template: `
    FROM ubuntu:22.04
    RUN pip3 install anthropic openai langchain
    `,
      alias: 'llm-agent',
      cpuCount: 2,
      memoryMb: 1024,
      onBuildLogs: (line) => console.log(line),
    });
    ```
  </Tab>
</Tabs>

## TemplateBase model

`TemplateBase` describes a template configuration before it is built.

| Field        | Type             | Description                                             |
| ------------ | ---------------- | ------------------------------------------------------- |
| `template`   | `str`            | Dockerfile content for the template image               |
| `alias`      | `str \| None`    | Human-readable name for the template                    |
| `cpu_count`  | `int`            | Default vCPUs for sandboxes from this template (1–8)    |
| `memory_mb`  | `int`            | Default RAM for sandboxes from this template (128–8192) |
| `copy_files` | `list[CopyItem]` | Files to copy into the template at build time           |

## Copy files into a template

Use `CopyItem` to embed files from the host into the template image at build time.

```python theme={null}
from declaw import Template, CopyItem

template = Template.build(
    template="""
FROM ubuntu:22.04
RUN pip3 install -r /workspace/requirements.txt
""",
    copy_files=[
        CopyItem(
            source_path="./requirements.txt",
            dest_path="/workspace/requirements.txt",
        ),
        CopyItem(
            source_path="./scripts/",
            dest_path="/workspace/scripts/",
        ),
    ],
    alias="my-project",
)
```

### CopyItem model

| Field         | Type  | Description                                |
| ------------- | ----- | ------------------------------------------ |
| `source_path` | `str` | Path on the host machine                   |
| `dest_path`   | `str` | Destination path inside the template image |

## Start background build

Use `build_in_background()` to start a build without waiting, then poll the status.

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    build_id = Template.build_in_background(
        template="""
    FROM ubuntu:22.04
    RUN apt-get install -y heavy-dependency
    """,
        alias="slow-build",
    )
    print(f"Build started: {build_id}")
    ```
  </Tab>
</Tabs>

## Check build status

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    from declaw import TemplateBuildStatus
    import time

    while True:
        status = Template.get_build_status(build_id)
        print(status.status, status.progress)

        if status.status == TemplateBuildStatus.done:
            print(f"Template ready: {status.template_id}")
            break
        elif status.status == TemplateBuildStatus.error:
            print(f"Build failed: {status.error}")
            break

        time.sleep(2)
    ```
  </Tab>
</Tabs>

## BuildInfo model

| Field         | Type                  | Description                               |
| ------------- | --------------------- | ----------------------------------------- |
| `build_id`    | `str`                 | Unique build identifier                   |
| `template_id` | `str \| None`         | Set once build completes successfully     |
| `status`      | `TemplateBuildStatus` | `pending`, `building`, `done`, or `error` |
| `progress`    | `float`               | Build progress 0.0–1.0                    |
| `error`       | `str \| None`         | Error message if status is `error`        |
| `logs`        | `list[str]`           | Build log lines streamed during build     |

## TemplateBuildStatus enum

| Value      | Description                                |
| ---------- | ------------------------------------------ |
| `pending`  | Build queued, not yet started              |
| `building` | Build is in progress                       |
| `done`     | Build succeeded — `template_id` is set     |
| `error`    | Build failed — `error` contains the reason |

## Use a custom template

```python theme={null}
from declaw import Sandbox

sbx = Sandbox.create(template="data-science")
result = sbx.commands.run("python3 -c 'import pandas; print(pandas.__version__)'")
print(result.stdout)
```

Or by template ID:

```python theme={null}
sbx = Sandbox.create(template="tpl-abc123")
```

## Async template operations

```python theme={null}
from declaw import AsyncTemplate

template = await AsyncTemplate.build(
    template="""
FROM ubuntu:22.04
RUN pip3 install torch transformers
""",
    alias="ml-inference",
)
```

<Info>
  Template builds run on the server. Build time depends on the packages being installed and typically takes 1–5 minutes. Use `build_in_background()` for large builds to avoid blocking your process.
</Info>
