Skip to main content
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

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.

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 below.

Worked examples

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

base — shell tools

Run git, curl, and jq end-to-end inside a fresh sandbox.

python — pandas analysis

Pipe a CSV through pandas and read back JSON results.

node — TypeScript script

Compile a .ts file with tsc and run the output with Node.js 20.

ai-agent — frameworks check

Boot an agent sandbox and verify the major LLM-framework SDKs import.

ai-agent — KYC with CrewAI

Fintech: four-agent CrewAI KYC pipeline with PII + injection defense.

ai-agent — prior auth with LangGraph

Health-tech: LangGraph workflow with PHI redact + rehydrate around GPT-4.1.

Build a custom template

Use Template.build() when none of the built-ins fit — most commonly when you need extra system or Python packages, or a different base image. Describe the image with TemplateBase, using its helpers or a Dockerfile, and give the template an alias: sandboxes are created from it by that name. build() waits for the build to finish, which usually takes several minutes.

Build from a Dockerfile, with options

A Dockerfile build keeps only the files the Dockerfile produces. Its ENV, WORKDIR and CMD are not applied to sandboxes, and in Python and TypeScript the builder methods (set_envs(), apt_install(), run_cmd(), …) are ignored on a Dockerfile template. Pass environment variables when you create the sandbox (envs), and give commands a working directory with cwd.

Build options

Copying local files

TemplateBase.copy() is not supported yet. A template build cannot upload local files, so building a template that uses copy() raises InvalidArgumentError. Download files in a run_cmd step (for example curl -fsSL -o /workspace/app.py https://...), or bake them into a Dockerfile.

Start a background build

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

Check build status

BuildInfo model

Build status values

Template lifecycle

A custom template is immutable once built. The lifecycle is:
Ready templates cannot be changed. To alter a template’s contents, delete it and create a new one. Rebuilding a live template would replace its image while workers already running it kept serving the old one, so the API refuses it with 409 template_immutable. A failed build is recoverable. POST /templates/{template_id}/rebuild re-runs the stored spec — it does not accept a new one. Use it when a build failed, or when a build was interrupted. Returns 202; poll GET /templates/builds/{build_id} for the result. A failed template keeps its alias, so building again under that alias returns 409: to build a changed spec under the same name, delete the failed template first (declaw template delete <template-id>). Sandboxes require a ready template. Creating a sandbox against a template that is still building or whose build failed returns 409 template_not_ready rather than starting a sandbox on a missing or half-written image. Built-in templates are always ready.
A build interrupted by a control-plane restart is marked failed automatically after a timeout, so it never stays stuck in building. Rebuild it once that happens.

Use a custom template

Create sandboxes from a custom template by its alias:
The template ID (tpl-…) identifies the template in GET and DELETE /templates/{template_id}; sandbox creation does not accept it in place of the alias.

Async template operations

Template builds run on the server and usually take several minutes, depending on what is installed. build() waits for the build to finish (up to build_timeout); use build_in_background() to return immediately and poll get_build_status() instead.