- Snapshots are Docker/OCI images configured with your dev stack
- Launch in milliseconds from warm pool
- Created via Dashboard or API
- Can be:
- Public images (node:20, python:3.11)
- Private registries
- Custom Dockerfiles
- Declarative Builder
- Created from snapshots using SDK
- Get unique ID and preview URL
- Can be:
- Public: Anyone with link can access
- Private: Only org members + token required
- Preview URLs:
https://PORT-sandbox-ID.proxy.daytona.work
- API Key from dashboard (with scopes)
- Sandbox
publicflag:true= public accessfalse= org-only + token auth
- Token in header:
x-daytona-preview-token: TOKEN
import { Daytona } from '@daytonaio/sdk';
// Initialize with API key
const daytona = new Daytona({
apiKey: process.env.DAYTONA_API_KEY
});
// Create sandbox from snapshot
const sandbox = await daytona.create({
snapshot: 'my-node-snapshot', // Pre-configured snapshot name
name: 'user-sandbox-123',
public: true // or false for private
});
// Get preview URL for port 3000
const preview = await sandbox.getPreviewUrl(3000);
console.log(preview.url); // https://3000-sandbox-xxx.proxy.daytona.work
console.log(preview.token); // Auth token for private sandboxes- Go to Daytona Dashboard
- Create snapshots for each template:
joepro-node- Node.js 20joepro-python- Python 3.11 + pipjoepro-react- Node + Vite + React templatejoepro-nextjs- Next.js 14 starterjoepro-fullstack- Node + PostgreSQLjoepro-ai- Python + Jupyter + TF
// lib/daytona/client.ts
import { Daytona } from '@daytonaio/sdk';
export const daytonaClient = new Daytona({
apiKey: process.env.DAYTONA_API_KEY!
});
// Map templates to snapshot names
export const SNAPSHOT_MAP = {
node: 'joepro-node',
python: 'joepro-python',
react: 'joepro-react',
nextjs: 'joepro-nextjs',
fullstack: 'joepro-fullstack',
ai: 'joepro-ai'
};
// Create sandbox
export async function launchSandbox(template: string) {
const snapshot = SNAPSHOT_MAP[template];
const sandbox = await daytonaClient.create({
snapshot,
public: true, // Users don't need accounts
name: `joepro-${template}-${Date.now()}`
});
// Get IDE preview URL (usually port 3000 or 8000)
const preview = await sandbox.getPreviewUrl(3000);
return {
id: sandbox.id,
url: preview.url,
token: preview.token // Include token for programmatic access
};
}// app/api/daytona/launch/route.ts
import { NextRequest, NextResponse } from 'next/server';
import { launchSandbox } from '@/lib/daytona/client';
export async function POST(req: NextRequest) {
const { template } = await req.json();
try {
const sandbox = await launchSandbox(template);
return NextResponse.json({ sandbox });
} catch (error: any) {
return NextResponse.json({ error: error.message }, { status: 500 });
}
}The existing UI works perfectly - just hits the API and opens the real preview URL.
- Fast Launch: Warm snapshots = millisecond startup
- No Auth Required: Public flag means instant access
- Full IDEs: VS Code in browser with preview URLs
- Your Credits: Uses your 20K Daytona credits
- Org Control: All sandboxes under your org dashboard
- Install SDK:
npm install @daytonaio/sdk - Get API key from dashboard
- Create snapshots for each template
- Update implementation with real SDK calls
- Test launch flow
- User clicks "Launch Sandbox" (Node.js)
- Backend creates sandbox from
joepro-nodesnapshot - Returns preview URL:
https://3000-sandbox-abc123.proxy.daytona.work - Frontend opens URL in new tab
- User sees VS Code with Node.js already configured
- Start coding immediately!
Since public: true, anyone with the link can access. This is fine for:
- Quick demos
- Public templates
- Temporary environments
For private/sensitive work, set public: false and implement token auth.