sandboxfeature

scripts and cloud runs

sandboxes that return data run in the cloud with no tab open, and a timeline sandbox renders to a video.

Not every sandbox draws. A script sandbox takes inputs, runs some JavaScript and returns data, and it runs in the cloud, so it works with every tab closed. A sandbox with a timeline turns a run into a video.

a script runs in the cloud, so no tab is needed.

script sandboxes

Set Kind to script — JS → JSON in the code editor's Settings tab, with index.js or index.ts as the entry. The code is one function:

export default async (inputs, { assets, file, loadPixels }) => value;

What the function returns becomes the node's output. A script can call fetch() to reach APIs, import its own local files, and use two helpers:

  • file(content, { ext, type }) declares a file as the run's result: an SVG, CSV, PDF, GLB, zip or anything else. The file is stored and its address becomes the node's output; the returned value rides along as text.
  • loadPixels(url) reads a picture into raw pixels (PNG, JPEG, WebP, GIF or SVG), scaled to fit 2,048 pixels on a side by default and 4,096 at most, so a script can trace, measure or recolour an image with no browser.

Press Run on the node, or wire it into a chain. Where a script keeps an API key, see secrets.

runs with no tab

The same cloud runner serves everyone who needs the result:

who runs itwhere it runs
you, pressing Run on a scriptthe cloud (a frame in your tab is the fallback)
a pixie in a process runthe cloud, even in a background run
a table's derived columnthe cloud (scripts run as scripts; plain HTML renders are photographed server-side)
an external tool through the MCP serverthe cloud

A render sandbox can opt in too. Ship a file named headless.js or headless.ts next to the frame code, exporting the same function shape, and no-tab runs use that twin while your tab keeps the live frame. Put shared work in a module both import, so the two cannot drift apart. A render with no twin runs in an open canvas tab.

limits per run

  • 30 seconds of CPU and 32 outgoing requests.
  • A declared file up to 25 MB.
  • Outgoing requests to private addresses (localhost, .local, internal ranges) are blocked.
  • The cloud has no console: return a diagnostic value or throw an Error with a clear message and it comes back as the run's error.

timeline video

Give a render sandbox a timeline and the node grows a strip underneath: play and pause, Looping or play-once, a length field (Timeline length (seconds)), a row for each clip, and a diamond row for each keyed input.

You build the timeline three ways:

  1. Clips from the code: it calls ixi.setTimeline({ duration, fps, clips }). Each clip is a named span with an easing or a spring, and the code receives its eased value on every frame.
  2. Keyframes with no code: click the key button beside any value input to key its current value at the playhead, then move the playhead and set it again. Drag diamonds to retime them; double-click to delete.
  3. A pixie writes either one for you.

The playhead belongs to ixi, not to the code, so scrubbing, playing and exporting all give the same pixels for the same time.

Pressing Run on a timeline node (its tooltip reads Render the timeline to a video) captures every frame at its exact time and encodes one file: an H.264 mp4 where your browser supports it, a gif otherwise. The node shows its progress as done/total, then encoding….

the playhead is ixi's, so scrubbing shows exactly what a render will.

good to know

  • The export runs in your open tab. It is made in the browser that pressed Run, so keep that tab open until it finishes. Closing it ends the render.
  • At most 600 frames. At 30 fps that is 20 seconds; at 60 fps, 10. A longer timeline renders its first 600 frames and says so.
  • fps runs from 1 to 60 (30 by default); a timeline holds up to 64 clips and 600 seconds.
  • A timeline node never re-runs on its own when an input changes, because a render takes minutes. Scrubbing is the live feedback; rendering is a decision.
  • A timeline sandbox cannot power a table column, because it needs a tab.

checked against the product · 2026-10-23