Install
@capsule-run/vpod/browser instead. The package root
resolves by export condition, which some bundlers get wrong for client code.
Overview
Everything is async, because loading the engine and fetching a snapshot are.
Persistent sessions
All calls share one running sandbox, so state carries across them. Declaring it withawait using closes it when the scope ends:
await using, call await sandbox.close()
yourself.
Shell commands and Python code share one filesystem:
Return values
sandbox.commands.run(cmd)
sandbox.code.run(source)
Timeouts
Both methods take atimeout in seconds. When it is reached the guest work is
interrupted and the call returns rather than waiting.
Interrupting a command
A command no longer has to run to its timeout.interrupt() stops whatever is in
the foreground, and commands.run() takes an AbortSignal for callers who would
rather set the deadline up front.
interrupt() resolves with an ordinary
result carrying exit code 130, because a terminal wants the exit code. A
signal rejects with signal.reason, so your own controller throws AbortError
and AbortSignal.timeout() throws TimeoutError.
The command really stops. This is not the caller walking away while the guest
keeps working, so the sandbox is yours again immediately.
code.run() cannot be interrupted yet. It accepts signal because it shares an
options type with commands.run(), but ignores it, so use timeout there.A command that ignores the interrupt runs to its own deadline and is recovered
the same way a timeout is.Sandbox.create() options
snapshot
A registry name, or a snapshot you built yourself:
The first
Sandbox.create() downloads the snapshot and caches it, on disk in Node
and in origin-private storage in a browser. Later runs use the cache. See
Snapshots.network
The guest’s network is on by default wherever it can be. Pass false to run
fully offline, or true to fail loudly instead of silently starting without it:
sandbox.network reports what the guest can actually reach:
Differences from the Python SDK
Three things differ, and all three surprise people who move between the two:
- The default snapshot is
vsnap-base:latesthere andalpinein Python. sandbox.suspend()returns the delta bytes, not an instance id. Browsers have nowhere to put a file, so where the state goes is your decision. See Suspend & resume.- There is no
mountsoption. Mounting a host directory has no meaning in a browser tab, so the TypeScript SDK does not offer it anywhere.