Skip to main content
import { Template, TemplateBase } from '@declaw/sdk';
import type { BuildInfo, TemplateBuildStatus, CopyItem, TemplateBuildOpts, GetBuildStatusOpts } from '@declaw/sdk';
Templates let you pre-build sandbox images with specific packages, files, and environment variables. Once built, reference a template by alias in Sandbox.create({ template: 'my-alias' }).

TemplateBase

TemplateBase is a fluent class for defining template contents. Chain methods to build the definition, then pass it to Template.build().
import { TemplateBase } from '@declaw/sdk';

const template = new TemplateBase()
  .fromBaseImage('ubuntu:22.04')
  .aptInstall('python3', 'python3-pip', 'nodejs', 'npm')
  .runCmd(['pip3', 'install', 'pandas', 'numpy'])
  .copy('./local_setup.sh', '/usr/local/bin/setup.sh', 0o755)
  .setEnvs({ PYTHONPATH: '/home/user', NODE_ENV: 'production' })
  .setStartCmd('sleep infinity');

.fromBaseImage(image?)

Set the base Docker image.
image
string
default:"'ubuntu:22.04'"
Docker image tag.
Returns this

.aptInstall(...packages)

Install apt packages.
template.aptInstall('git', 'curl', 'jq');
packages
string[]
required
One or more package names to install via apt-get install.
Returns this

.runCmd(cmds)

Add a build-time command (equivalent to a Dockerfile RUN).
template.runCmd(['pip3', 'install', 'torch', '--index-url', 'https://download.pytorch.org/whl/cpu']);
cmds
string[]
required
Command as an array of strings (executable + arguments).
Returns this

.copy(src, dst, mode?)

Copy a local file into the image at build time.
template.copy('./requirements.txt', '/app/requirements.txt');
template.copy('./startup.sh', '/usr/local/bin/startup.sh', 0o755);
src
string
required
Local path to the file.
dst
string
required
Destination path inside the image.
mode
number
Unix file permission bits (e.g. 0o755 for executable).
Returns this

.setEnvs(envs)

Set environment variables baked into the image.
template.setEnvs({ APP_ENV: 'production', PORT: '8080' });
envs
Record<string, string>
required
Key-value pairs to set as environment variables.
Returns this

.setStartCmd(cmd)

Set a command to run when the sandbox boots.
template.setStartCmd('python3 /app/server.py');
cmd
string
required
Shell command to execute on sandbox start.
Returns this

.toJSON()

Serialize the template to a JSON-friendly object for the API. Returns Record<string, any>

Template

Template is a static class for submitting and querying template builds. All methods are async.

Template.build()

Submit a template build and wait for completion.
import { Template, TemplateBase } from '@declaw/sdk';

const template = new TemplateBase()
  .aptInstall('python3-pip')
  .runCmd(['pip3', 'install', 'pandas']);

const info: BuildInfo = await Template.build(template, 'data-analysis', {
  cpuCount: 2,
  memoryMb: 2048,
  onBuildLogs: (log) => console.log(log),
  apiKey: 'your-api-key',
  domain: '104.198.24.180:8080',
});

console.log('Template ID:', info.templateId);
template
TemplateBase
required
The template definition to build.
alias
string
required
Human-readable name used as template in Sandbox.create().
opts
TemplateBuildOpts
Optional build options.

TemplateBuildOpts

cpuCount
number
Number of CPUs for the build worker.
memoryMb
number
Memory in MB for the build worker.
onBuildLogs
(log: string) => void
Callback invoked for each log line during the build.
apiKey
string
API key override.
domain
string
Domain override.
requestTimeout
number
Per-request HTTP timeout in milliseconds.
Returns Promise<BuildInfo>

Template.buildInBackground()

Submit a template build and return immediately without waiting.
const info = await Template.buildInBackground(template, 'my-template', {
  apiKey: 'your-api-key',
  domain: '104.198.24.180:8080',
});
console.log('Build started:', info.buildId);
Parameters are the same as Template.build() except onBuildLogs is excluded. Returns Promise<BuildInfo>

Template.getBuildStatus()

Poll the status of a background build.
const status = await Template.getBuildStatus('build-id', {
  apiKey: 'your-api-key',
  domain: '104.198.24.180:8080',
});
console.log(status.status);       // "pending" | "running" | "succeeded" | "failed"
console.log(status.logs.at(-1));  // latest log line
buildId
string
required
Build ID from a previous build() or buildInBackground() call. Must be alphanumeric with hyphens/underscores.
opts
GetBuildStatusOpts
Optional: apiKey, domain, requestTimeout.
Returns Promise<TemplateBuildStatus>

Data models

BuildInfo

interface BuildInfo {
  buildId: string;
  status: string;
  templateId?: string;  // Set once build succeeds
}

TemplateBuildStatus

interface TemplateBuildStatus {
  buildId: string;
  status: string;      // "pending" | "running" | "succeeded" | "failed"
  logs: string[];      // Accumulated build log lines
}

CopyItem

interface CopyItem {
  src: string;
  dst: string;
  mode?: number;
}

GetBuildStatusOpts

interface GetBuildStatusOpts {
  apiKey?: string;
  domain?: string;
  requestTimeout?: number;
}

Polling a background build

import { Template, TemplateBase } from '@declaw/sdk';

const template = new TemplateBase()
  .aptInstall('nodejs', 'npm')
  .runCmd(['npm', 'install', '-g', 'typescript']);

const info = await Template.buildInBackground(template, 'node-ts', {
  apiKey: 'your-api-key',
  domain: '104.198.24.180:8080',
});

let status = await Template.getBuildStatus(info.buildId, {
  apiKey: 'your-api-key',
  domain: '104.198.24.180:8080',
});

while (status.status === 'pending' || status.status === 'running') {
  await new Promise((r) => setTimeout(r, 3000));
  status = await Template.getBuildStatus(info.buildId, {
    apiKey: 'your-api-key',
    domain: '104.198.24.180:8080',
  });
  console.log(`Build ${status.status}: ${status.logs.at(-1) ?? ''}`);
}

if (status.status !== 'succeeded') {
  throw new Error('Template build failed');
}

Using a template

import { Sandbox } from '@declaw/sdk';

const sbx = await Sandbox.create({
  template: 'data-analysis',  // alias set during build
  apiKey: 'your-api-key',
  domain: '104.198.24.180:8080',
});

// pandas is already installed
const result = await sbx.commands.run(
  'python3 -c "import pandas; print(pandas.__version__)"',
);
console.log(result.stdout);
await sbx.kill();