Daytona SDK v0.21.0: Breaking Changes & Migration Guide
A major upgrade to the Daytona SDK is coming this Sunday, with breaking changes that simplify sandbox creation, standardize resource management, and lay the foundation for a more powerful snapshot-based workflow.
Why This Matters
In v0.21.0, we’re introducing a more robust architecture centered around snapshots, replacing the legacy pre-built image flow. This refactor enables better caching, more declarative sandbox provisioning, and consistent behavior across TypeScript and Python implementations.
This upcoming release includes breaking changes, which means if you're using v0.20.2 or earlier, you’ll need to update your integration to keep things working as expected, especially if you rely on the declarative image builder.
Migration Timeline
Old version: v0.20.2
New version: v0.21.0
Compatibility: The refactored backend is temporarily backward-compatible, but declarative image builder support will break for v0.20.2.
Recommended action: Upgrade to v0.21.0 now to access new features and ensure continued support.
🛠 Maintenance Notice
To support this SDK upgrade, scheduled downtime will occur on Sunday, June 15th, from 03:00 to 03:30 Pacific Time. Services may be temporarily unavailable during this window.
🔄 Key Changes Overview
Image creation → Snapshot creation
A more powerful snapshot abstraction replaces pre-built images.New parameter types for sandbox creation
CreateSandboxParams
is now split into more explicit types.New
Resources
object
Resource configuration is standardized and explicit.Renamed callback parameters
All callback-related options now reflect the snapshot-based flow.New Snapshot Service
Easily list, create, delete, and inspect snapshots from your SDK.Removed
SandboxTargetRegion
enum
Define target region using a plain string value.Reduced verbosity of method for retrieving a single Sandbox
A more conciseget
method is now available on theDaytona
object.Removed deprecated aliases for Sandbox methods
Using deprecated workspace methods is no longer supported.Flattened Sandbox instance information
Sandbox details are now only available as top-level properties.Removed legacy Sandbox properties
Name and class are no longer present on the Sandbox object.Improved functionality for refreshing Sandbox information
The new method updates the Sandbox object properties directly.
1. Images → Snapshots
Snapshots now power sandbox creation. Here’s how the change looks in practice:
TypeScript
Before:
1// Creating a pre-built image2const imageName = `example:${Date.now()}`;3await daytona.createImage(imageName, image, { onLogs: console.log });4// Using the pre-built image5const sandbox = await daytona.create(6 { image: imageName }7);
After:
1// Creating a snapshot2const snapshotName = `example:${Date.now()}`;3await daytona.snapshot.create(4 {5 name: snapshotName,6 image,7 resources: {8 cpu: 1,9 memory: 1,10 disk: 3,11 },12 },13 { onLogs: console.log }14);15// Using the snapshot16const sandbox = await daytona.create({17 snapshot: snapshotName,18});
Python
Before:
1# Creating a pre-built image2image_name = f"python-example:{int(time.time())}"3daytona.create_image(image_name, image, on_logs=print)4# Using the pre-built image5sandbox = daytona.create(6 CreateSandboxParams(image=image_name),7)
After:
1# Creating a snapshot2snapshot_name = f"python-example:{int(time.time())}"3daytona.snapshot.create(4 CreateSnapshotParams(5 name=snapshot_name,6 image=image,7 resources=Resources(8 cpu=1,9 memory=1,10 disk=3,11 ),12 ),13 on_logs=print,14)15# Using the snapshot16sandbox = daytona.create(17 CreateSandboxFromSnapshotParams(snapshot=snapshot_name)18)
2. New Parameter Types for Sandbox Creation
We’ve replaced the all-in-one CreateSandboxParams
with more specific options, depending on whether you’re creating from an image or a snapshot.
TypeScript
🧩 Old SDK – Single Parameter Class
1// Basic creation2const sandbox = await daytona.create({3 language: "typescript",4});56// With image and callback7const sandbox = await daytona.create(8 {9 image: Image.debianSlim("3.12"),10 resources: {11 cpu: 2,12 memory: 4,13 disk: 20,14 },15 },16 { onImageBuildLogs: console.log }17);1819// With language and resources20const sandbox = await daytona.create({21 language: "typescript",22 resources: {23 cpu: 2,24 memory: 4,25 },26});
🚀 New SDK – Specific Parameter Classes
1// Basic creation (unchanged for simple use cases)2const sandbox = await daytona.create({3 language: "typescript",4});56// Creating from image. A dynamic snapshot will be created and used to initialize the sandbox.7const sandbox = await daytona.create(8 {9 image: Image.debianSlim("3.12"),10 resources: {11 cpu: 2,12 memory: 4,13 disk: 20,14 },15 },16 {17 onSnapshotCreateLogs: console.log, // renamed from onImageBuildLogs18 }19);2021// Creating from snapshot22const sandbox = await daytona.create({23 snapshot: "my-snapshot-name",24});
Python
🧩 Old SDK – Single Parameter Class
1# Basic creation2params = CreateSandboxParams(language="python")3sandbox = daytona.create(params)45# With image6params = CreateSandboxParams(7 language="python",8 image=Image.debian_slim("3.12")9)10sandbox = daytona.create(params, on_image_build_logs=print)1112# With language and resources13params = CreateSandboxParams(14 language="python",15 resources=SandboxResources(16 cpu=1,17 memory=1,18 disk=3,19 ),20)21sandbox = daytona.create(params)
🚀 New SDK – Specific Parameter Classes
1# Basic creation (unchanged for simple cases)2params = CreateSandboxFromSnapshotParams(language="python")3sandbox = daytona.create(params)45# Creating from image. A dynamic snapshot will be created and used to initialize the sandbox.6params = CreateSandboxFromImageParams(7 image=Image.debian_slim("3.12"),8 language="python",9 resources=Resources(10 cpu=1,11 memory=1,12 disk=3,13 ),14)15sandbox = daytona.create(params, timeout=150, on_snapshot_create_logs=print)1617# Creating from snapshot18params = CreateSandboxFromSnapshotParams(19 snapshot="my-snapshot-name",20 language="python",21)22sandbox = daytona.create(params)
3. Standardized Resource Configuration
We've unified resource definitions under a single Resources
object across SDKs.
Old | New |
---|---|
SandboxResources | Resources |
This improves clarity and aligns with our declarative execution model.
4. Updated Callback Names
To reflect the shift to snapshots:
Old | New |
---|---|
onImageBuildLogs | onSnapshotCreateLogs |
5. New Snapshot Service
You can now manage snapshots directly via a dedicated SDK interface.
TypeScript
1// Access snapshot operations2await daytona.snapshot.create(params);3await daytona.snapshot.list();4await daytona.snapshot.get(snapshotName);5await daytona.snapshot.delete(snapshot);
Python
1# Access snapshot operations2daytona.snapshot.create(params)3daytona.snapshot.list()4daytona.snapshot.get(snapshot_name)5daytona.snapshot.delete(snapshot)
6. Removed SandboxTargetRegion Enum
Target region has to be specified using a simple string value instead of an enum. Here’s how the change looks in practice:
TypeScript
Before:
1const daytona: Daytona = new Daytona({2 target: SandboxTargetRegion.US3});
After:
1const daytona: Daytona = new Daytona({2 target: "us"3});
Python
Before:
1config = DaytonaConfig(2 target=SandboxTargetRegion.EU3)45daytona = Daytona(config)
After:
1config = DaytonaConfig(2 target="eu"3)45daytona = Daytona(config)
7. Reduced Verbosity of Method for Retrieving a Single Sandbox
A more concise get
method is now available on the Daytona
object. Here’s how the change looks in practice:
TypeScript
Before:
1// Get sandbox by id2const sandbox = daytona.getCurrentSandbox(id)
After:
1// Get sandbox by id2const sandbox = daytona.get(id)
Python
Before:
1# Get sandbox by id2sandbox = daytona.get_current_sandbox(id)
After:
1# Get sandbox by id2sandbox = daytona.get(id)
8. Removed Deprecated Aliases for Sandbox Methods
Using deprecated workspace methods is no longer supported. Here’s how the change looks in practice:
TypeScript
Before:
1// Get workspace by id2const workspace = daytona.getCurrentWorkspace(id)34// Get the root directory path5const dir = workspace.getWorkspaceRootDir()67// Search for all symbols containing "TODO"8const lsp = await workspace.createLspServer('typescript', 'workspace/project')9const symbols = await lsp.workspaceSymbols('TODO');1011// Convert an API workspace instance to a WorkspaceInfo object12const info = Workspace.toWorkspaceInfo(apiWorkspace)
After:
1// Get sandbox by id2const sandbox = daytona.get(id)34// Get the root directory path5const dir = sandbox.getUserRootDir()67// Search for all symbols containing "TODO"8const lsp = await sandbox.createLspServer('typescript', 'workspace/project')9const symbols = await lsp.sandboxSymbols('TODO');1011// Convert an API sandbox instance to a SandboxInfo object12const info = Sandbox.toSandboxInfo(apiSandbox)
Python
Before:
1# Get workspace by id2workspace = daytona.get_current_workspace(id)34# Get the root directory path5dir = workspace.get_workspace_root_dir()67# Search for all symbols containing "TODO"8lsp = workspace.create_lsp_server("python", "workspace/project")9symbols = lsp.workspace_symbols("TODO")1011# Wait for workspace to reach "started" state12workspace.wait_for_workspace_start()1314# Wait for workspace to reach "stopped" state15workspace.wait_for_workspace_stop()
After:
1# Get sandbox by id2sandbox = daytona.get(id)34# Get the root directory path5sandbox.get_user_root_dir()67# Search for all symbols containing "TODO"8lsp = sandbox.create_lsp_server("python", "workspace/project")9symbols = lsp.sandbox_symbols("TODO")1011# Wait for sandbox to reach "started" state12sandbox.wait_for_sandbox_start()1314# Wait for sandbox to reach "stopped" state15sandbox.wait_for_sandox_stop()
9. Flattened Sandbox Instance Information
Sandbox details are now available only as top-level properties. Here’s how the change looks in practice:
TypeScript
Before:
1const state = sandbox.instance.state2const autoStopInterval = sandbox.instance.autoStopInterval3const domain = sandbox.instance.info?.nodeDomain
After:
1const state = sandbox.state;2const autoStopInterval = sandbox.autoStopInterval3const domain = sandbox.runnerDomain
Python
Before:
1state = sandbox.instance.state2auto_stop_interval = sandbox.instance.auto_stop_interval3domain = sandbox.instance.info.node_domain
After:
1state = sandbox.state2auto_stop_interval = sandbox.auto_stop_interval3domain = sandbox.runner_domain
10. Removed Legacy Sandbox Properties
Name and class are no longer present on the Sandbox object. Here’s how the change looks in practice:
TypeScript
Before:
1// Valid2const sandboxName = sandbox.instance.name3const sandboxClass = sandbox.instance.info?.class
After:
1// Invalid2const sandboxName = sandbox.name;3const sandboxClass = sandbox.class
Python
Before:
1# Valid2name = workspace.instance.name3class_name = workspace.instance.info.class_name
After:
1# Invalid2name = workspace.name3class_name = workspace.class_name
11. Improved Functionality for Refreshing Sandbox Information
The new method updates the Sandbox object properties directly. Here’s how the change looks in practice for some of the Sandbox properties:
TypeScript
Before:
1// Get up-to-date sandbox info2const info = await sandbox.info()
After:
1// Update sandbox with up-to-date info2await sandbox.refreshData()
Python
Before:
1# Get up-to-date sandbox info2info = sandbox.info()
After:
1# Update sandbox with up-to-date info2sandbox.refresh_data()
✅ Migration Checklist
For TypeScript Users
Replace all
daytona.createImage()
calls withdaytona.snapshot.create()
Use
CreateSandboxFromImageParams
orCreateSandboxFromSnapshotParams
when creating sandboxesReplace all instances of
SandboxResources
withResources
Rename
onImageBuildLogs
callbacks toonSnapshotCreateLogs
Replace
SandboxTargetRegion
enum with plain string values (e.g.,"us"
,"eu"
)Replace retrieving a single Sandbox using
daytona.getCurrentSandbox(id)
todaytona.get(id)
Replace deprecated
daytona.getCurrentWorkspace(id)
withdaytona.get(id)
Replace deprecated
workspace.getWorkspaceRootDir()
withsandbox.getUserRootDir()
Replace deprecated
lspServer.workspaceSymbols(query)
withlspServer.sandboxSymbols(query)
Replace deprecated
Workspace.toWorkspaceInfo(apiWorkspace)
withSandbox.toSandboxInfo(apiSandbox)
Update reading Sandbox details to use top-level properties instead of reading from
sandbox.instance
Remove references to legacy sandbox properties (
name
,class
)Replace using
sandbox.info()
to get up-to-date Sandbox info withsandbox.refreshData()
to update the Sandbox properties directly
For Python Users
Replace all
daytona.create_image()
calls withdaytona.snapshot.create()
Import and use:
CreateSnapshotParams
,CreateSandboxFromImageParams
,CreateSandboxFromSnapshotParams
, andResources
Replace all usage of
CreateSandboxParams
with the appropriate class (CreateSandboxFromImageParams
orCreateSandboxFromSnapshotParams
)Replace all usage of
SandboxResources
withResources
Rename
on_image_build_logs
callbacks toon_snapshot_create_logs
Replace
SandboxTargetRegion
enum with plain string values (e.g.,"us"
,"eu"
)Replace retrieving a single Sandbox using
daytona.get_current_sandbox(id)
todaytona.get(id)
Replace deprecated
daytona.get_current_workspace(id)
withdaytona.get(id)
Replace deprecated
workspace.get_workspace_root_dir()
withsandbox.get_user_root_dir()
Replace deprecated
lsp_server.workspace_symbols(query)
withlsp_server.sandbox_symbols(query)
Replace using deprecated methods
workspace.wait_for_workspace_start()
andworkspace.wait_for_workspace_stop()
withsandbox.wait_for_sandbox_start()
andsandbox.wait_for_sandbox_stop()
Update reading Sandbox details to use top-level properties instead of reading from
sandbox.instance
Remove references to legacy sandbox properties (
name
,class_name
)Replace using
sandbox.info()
to get up-to-date Sandbox info withsandbox.refresh_data()
to update the Sandbox properties directly
Final Notes
This release unlocks a more powerful and flexible infrastructure model across all SDKs.
If you're using Cursor, you can find an example here that you can add to your Project Rules to help with the migration.
If you need help migrating or want to discuss your use case, reach out via:
In-app support widget
Email: support@daytona.io
We’re excited to see what you build with it.
📚 You can also find full API and SDK reference at daytona.io/docs.