diff --git a/docs.json b/docs.json
index f1410c9..ef883d6 100644
--- a/docs.json
+++ b/docs.json
@@ -37,157 +37,60 @@
]
},
"docs/api-key",
- "docs/cookbook",
- "docs/support"
+ "docs/sdks-explained"
]
},
{
- "group": "Code Interpreting",
+ "group": "Use Case Examples",
"pages": [
- {
- "group": "Analyze data with AI",
- "pages": [
- "docs/code-interpreting/analyze-data-with-ai",
- "docs/code-interpreting/analyze-data-with-ai/pre-installed-libraries"
- ]
- },
- {
- "group": "Charts & visualizations",
- "pages": [
- "docs/code-interpreting/create-charts-visualizations",
- "docs/code-interpreting/create-charts-visualizations/static-charts",
- "docs/code-interpreting/create-charts-visualizations/interactive-charts"
- ]
- },
- "docs/code-interpreting/streaming",
- {
- "group": "Supported languages",
- "pages": [
- "docs/code-interpreting/supported-languages",
- "docs/code-interpreting/supported-languages/python",
- "docs/code-interpreting/supported-languages/javascript",
- "docs/code-interpreting/supported-languages/r",
- "docs/code-interpreting/supported-languages/java",
- "docs/code-interpreting/supported-languages/bash"
- ]
- }
+ "docs/use-cases/linux-desktop",
+ "docs/use-cases/deep-research-agents",
+ "docs/use-cases/ai-data-analysis-visualization",
+ "docs/use-cases/reinforcement-learning",
+ "docs/use-cases/vibe-coding"
]
},
{
- "group": "Sandbox",
+ "group": "Dashboard",
"pages": [
- "docs/sandbox",
- "docs/sandbox/lifecycle-events-api",
- "docs/sandbox/lifecycle-events-webhooks",
- "docs/sandbox/persistence",
- "docs/sandbox/metrics",
- "docs/sandbox/metadata",
- "docs/sandbox/environment-variables",
- "docs/sandbox/list",
- "docs/sandbox/connect",
- "docs/sandbox/internet-access",
- "docs/sandbox/connect-bucket",
- "docs/sandbox/rate-limits",
- "docs/sandbox/secured-access"
+ "docs/dashboard/billing",
+ "docs/dashboard/usage",
+ "docs/dashboard/webhooks",
+ "docs/dashboard/templates"
]
},
{
- "group": "Templates",
- "pages": [
- "docs/template/quickstart",
- "docs/template/how-it-works",
- "docs/template/user-and-workdir",
- "docs/template/caching",
- "docs/template/base-image",
- "docs/template/private-registries",
- "docs/template/defining-template",
- "docs/template/start-ready-command",
- "docs/template/build",
- "docs/template/logging",
- "docs/template/error-handling",
- {
- "group": "Examples",
- "pages": [
- "docs/template/examples/nextjs",
- "docs/template/examples/nextjs-bun",
- "docs/template/examples/expo",
- "docs/template/examples/desktop",
- "docs/template/examples/claude-code"
- ]
- },
- "docs/template/migration-v2",
- {
- "group": "Legacy Docs",
- "pages": [
- "docs/sandbox-template",
- "docs/sandbox-template/start-cmd",
- "docs/sandbox-template/ready-cmd",
- "docs/sandbox-template/customize-cpu-ram"
- ]
- }
- ]
- },
- {
- "group": "Filesystem",
+ "group": "Sandbox",
"pages": [
- "docs/filesystem",
- "docs/filesystem/read-write",
- "docs/filesystem/info",
- "docs/filesystem/watch",
- "docs/filesystem/upload",
- "docs/filesystem/download"
+ "docs/sandbox/intro",
+ "docs/sandbox/executing-code",
+ "docs/sandbox/reading-output",
+ "docs/sandbox/persistence",
+ "docs/sandbox/security"
]
},
{
- "group": "Commands",
+ "group": "Templates",
"pages": [
- "docs/commands",
- "docs/commands/streaming",
- "docs/commands/background"
+ "docs/templates/intro"
]
},
{
- "group": "MCP Gateway",
+ "group": "Code Interpreter",
"pages": [
- "docs/mcp",
- "docs/mcp/quickstart",
- "docs/mcp/available-servers",
- "docs/mcp/custom-templates",
- "docs/mcp/custom-servers",
- "docs/mcp/examples"
+ "docs/code-interpreter"
]
},
{
- "group": "CLI",
+ "group": "Desktop",
"pages": [
- "docs/cli",
- "docs/cli/auth",
- "docs/cli/list-sandboxes",
- "docs/cli/shutdown-sandboxes"
+ "docs/desktop/intro"
]
},
{
- "group": "Deployment",
- "pages": ["docs/byoc"]
- },
- {
- "group": "Migration",
- "pages": ["docs/migration/v2"]
- },
- {
- "group": "Troubleshooting",
+ "group": "FAQ",
"pages": [
- {
- "group": "SDKs",
- "pages": ["docs/troubleshooting/sdks/workers-edge-runtime"]
- },
- {
- "group": "Templates",
- "pages": [
- "docs/troubleshooting/templates/build-authentication-error",
- "docs/troubleshooting/templates/49999-port-not-open"
- ]
- }
+ "docs/faq"
]
}
]
diff --git a/docs.mdx b/docs.mdx
index a330775..ec04f59 100644
--- a/docs.mdx
+++ b/docs.mdx
@@ -4,37 +4,41 @@ sidebarTitle: Home
icon: house
---
-import { Concepts } from '/snippets/Concepts.jsx';
-import { CodeInterpreting } from '/snippets/CodeInterpreting.jsx';
import { Quickstart } from '/snippets/Quickstart.jsx';
+import { CodeInterpreting } from '/snippets/CodeInterpreting.jsx';
-Here you'll find all the guides, concepts, and SDK references for developing with E2B.
+## What is E2B?
-
-```bash JavaScript & TypeScript
-npm i @e2b/code-interpreter
-```
-```bash Python
-pip install e2b-code-interpreter
-```
-
+E2B provides isolated sandboxes that let agents safely execute code, process data, and run tools. Our [SDKs](/docs/sdks-explained) make it easy to start and manage these environments.
-## What is E2B?
-E2B is an [open-source](https://github.com/e2b-dev) infrastructure that allows you to run AI-generated code in secure isolated sandboxes in the cloud.
-To start and control sandboxes, use our [Python SDK](https://pypi.org/project/e2b/) or [JavaScript SDK](https://www.npmjs.com/package/e2b).
+## E2B Building Blocks
+
+A quick overview of the core building blocks you'll interact with when using E2B.
+
+- [**Sandbox**]() — A fast, secure Linux VM created on demand for your agent
+
+- [**Template**]() — Defines what environment a sandbox starts with
+
+## How to use the docs
+
+The documentation is split into three main sections:
+
+- [**Quickstart**](#quickstart) — Step-by-step tutorials that walk you through spinning up your first E2B sandboxes.
-Some of the typical use cases for E2B are AI data analysis or visualization, running AI-generated code of various languages, playground for coding agents, environment for codegen evals, or running full AI-generated apps like in [Fragments](https://github.com/e2b-dev/fragments).
+- [**Examples**](#examples) — In-depth tutorials focused on specific use cases. Pick the topics that match what you're building.
-### Under the hood
-The E2B Sandbox is a small isolated VM the can be started very quickly (~150ms). You can think of it as a small computer for the AI model. You can run many sandboxes at once. Typically, you run separate sandbox for each LLM, user, or AI agent session in your app.
-For example, if you were building an AI data analysis chatbot, you would start the sandbox for every user session.
+- [**API/SDK Reference**](https://e2b.dev/docs/sdk-reference) — A complete technical reference for every feature, component, and configuration option.
-## Quickstart
-
+## 🚀 Quickstart.
-## Code interpreting with AI
-
+
-## Learn the core concepts
-
+## 🧠 Examples
+
+
+
+
+
+
+
diff --git a/docs/code-interpreter.mdx b/docs/code-interpreter.mdx
new file mode 100644
index 0000000..db68a6c
--- /dev/null
+++ b/docs/code-interpreter.mdx
@@ -0,0 +1,213 @@
+---
+title: "Code Interpreter"
+description: "Multi-language code execution with pre-installed data science libraries, visualization support, and built on top of the core E2B SDK."
+icon: "code"
+---
+
+# Code Interpreter
+
+Built on top of `e2b` with added support for multi-language code execution (Python, JavaScript, R, Java, Bash), pre-installed data science libraries, and visualization capabilities.
+
+
+Includes **all features from `e2b`** plus specialized code execution methods and pre-configured environment.
+
+
+## Installation
+
+
+```bash Python
+pip install e2b-code-interpreter
+```
+
+```bash JavaScript
+npm install @e2b/code-interpreter
+```
+
+
+## Quick Start
+
+
+```python Python
+from e2b_code_interpreter import Sandbox
+
+# Create code interpreter
+sbx = Sandbox()
+
+# Execute Python with visualization
+execution = sbx.run_code("""
+import matplotlib.pyplot as plt
+plt.plot([1, 2, 3, 4])
+plt.ylabel('some numbers')
+plt.savefig('chart.png')
+""")
+
+# Access results
+for result in execution.results:
+ print(result)
+
+sbx.close()
+```
+
+```typescript JavaScript
+import { Sandbox } from '@e2b/code-interpreter'
+
+// Create code interpreter
+const sbx = await Sandbox.create()
+
+// Execute Python with visualization
+const execution = await sbx.runCode(`
+import matplotlib.pyplot as plt
+plt.plot([1, 2, 3, 4])
+plt.ylabel('some numbers')
+plt.savefig('chart.png')
+`)
+
+// Access results
+execution.results.forEach(result => console.log(result))
+
+await sbx.close()
+```
+
+
+## Supported Languages
+
+
+
+ Full Python support with data science libraries
+
+
+ Node.js runtime for JavaScript execution
+
+
+ Statistical computing with R
+
+
+ Java code execution
+
+
+ Shell scripts and commands
+
+
+
+## Pre-installed Libraries
+
+The code interpreter comes with popular data science and visualization libraries:
+
+
+
+ - **Data Analysis:** pandas, numpy, scipy
+ - **Visualization:** matplotlib, seaborn, plotly
+ - **Machine Learning:** scikit-learn
+ - **And many more...**
+
+ [View full list →](/docs/code-interpreting/analyze-data-with-ai/pre-installed-libraries)
+
+
+
+ - **Node.js built-in modules**
+ - **Popular npm packages** (install as needed)
+
+
+
+## Features
+
+### Code Execution Results
+
+Access execution results including stdout, stderr, charts, and data:
+
+
+```python Python
+execution = sbx.run_code("print('Hello'); 2 + 2")
+
+for result in execution.results:
+ if result.type == "stdout":
+ print(result.text)
+ elif result.type == "result":
+ print(result.data)
+```
+
+```typescript JavaScript
+const execution = await sbx.runCode("console.log('Hello'); 2 + 2")
+
+execution.results.forEach(result => {
+ if (result.type === 'stdout') {
+ console.log(result.text)
+ } else if (result.type === 'result') {
+ console.log(result.data)
+ }
+})
+```
+
+
+### Chart Generation
+
+Create and retrieve visualizations:
+
+
+```python Python
+execution = sbx.run_code("""
+import matplotlib.pyplot as plt
+import numpy as np
+
+x = np.linspace(0, 10, 100)
+plt.plot(x, np.sin(x))
+plt.title('Sine Wave')
+plt.savefig('plot.png')
+""")
+
+# Charts are available in results
+for result in execution.results:
+ if result.type == "image":
+ print(f"Chart saved: {result.url}")
+```
+
+```typescript JavaScript
+const execution = await sbx.runCode(`
+import matplotlib.pyplot as plt
+import numpy as np
+
+x = np.linspace(0, 10, 100)
+plt.plot(x, np.sin(x))
+plt.title('Sine Wave')
+plt.savefig('plot.png')
+`)
+
+// Charts are available in results
+execution.results.forEach(result => {
+ if (result.type === 'image') {
+ console.log(`Chart saved: ${result.url}`)
+ }
+})
+```
+
+
+## Use Cases
+
+
+
+ Build AI agents that analyze datasets and create visualizations
+
+
+ Create Jupyter-like environments for interactive coding
+
+
+ Generate reports with code, analysis, and charts
+
+
+ Run student code safely in sandboxed environments
+
+
+
+## Related Resources
+
+
+
+ Full list of available libraries
+
+
+ Chart generation guide
+
+
+ Complete API documentation
+
+
diff --git a/docs/dashboard/billing.mdx b/docs/dashboard/billing.mdx
new file mode 100644
index 0000000..f317ad1
--- /dev/null
+++ b/docs/dashboard/billing.mdx
@@ -0,0 +1,9 @@
+---
+title: "Billing"
+description: "Manage your E2B subscription, view pricing plans, and understand billing for sandbox usage, compute time, and storage."
+icon: "credit-card"
+---
+
+# Billing
+
+Content coming soon.
diff --git a/docs/dashboard/templates.mdx b/docs/dashboard/templates.mdx
new file mode 100644
index 0000000..00a55e0
--- /dev/null
+++ b/docs/dashboard/templates.mdx
@@ -0,0 +1,9 @@
+---
+title: "Templates"
+description: "Manage your custom sandbox templates in the E2B dashboard, including creating, editing, and deploying templates for your team."
+icon: "layer-group"
+---
+
+# Templates
+
+Content coming soon.
diff --git a/docs/dashboard/usage.mdx b/docs/dashboard/usage.mdx
new file mode 100644
index 0000000..dcdd291
--- /dev/null
+++ b/docs/dashboard/usage.mdx
@@ -0,0 +1,9 @@
+---
+title: "Usage"
+description: "Monitor your E2B usage metrics including active sandboxes, compute hours, API calls, and resource consumption across your projects."
+icon: "chart-simple"
+---
+
+# Usage
+
+Content coming soon.
diff --git a/docs/dashboard/webhooks.mdx b/docs/dashboard/webhooks.mdx
new file mode 100644
index 0000000..1c0b72f
--- /dev/null
+++ b/docs/dashboard/webhooks.mdx
@@ -0,0 +1,9 @@
+---
+title: "Webhooks"
+description: "Configure webhooks to receive real-time notifications about sandbox events, lifecycle changes, and system updates from E2B."
+icon: "webhook"
+---
+
+# Webhooks
+
+Content coming soon.
diff --git a/docs/desktop/intro.mdx b/docs/desktop/intro.mdx
new file mode 100644
index 0000000..33afe6f
--- /dev/null
+++ b/docs/desktop/intro.mdx
@@ -0,0 +1,118 @@
+---
+title: "Desktop Intro"
+description: "Full Linux desktop environment with GUI, browser automation, and window management built on top of the E2B SDK."
+icon: "desktop"
+---
+
+# Desktop
+
+Built on top of `e2b` with a full Linux desktop environment including GUI, browser, and window management capabilities.
+
+
+Includes **all features from `e2b`** plus desktop-specific methods like `getDesktopUrl()` and pre-configured GUI environment.
+
+
+## Installation
+
+
+```bash Python
+pip install e2b-desktop
+```
+
+```bash JavaScript
+npm install @e2b/desktop
+```
+
+
+## Quick Start
+
+
+```python Python
+from e2b_desktop import Sandbox
+
+# Create desktop sandbox
+sbx = Sandbox.create()
+
+# Get desktop URL
+desktop_url = sbx.get_desktop_url()
+print(f"Access desktop at: {desktop_url}")
+
+# Run GUI application
+sbx.commands.run("firefox https://example.com")
+```
+
+```typescript JavaScript
+import { Sandbox } from '@e2b/desktop'
+
+// Create desktop sandbox
+const sbx = await Sandbox.create()
+
+// Get desktop URL
+const desktopUrl = await sbx.getDesktopUrl()
+console.log(`Access desktop at: ${desktopUrl}`)
+
+// Run GUI application
+await sbx.commands.run('firefox https://example.com')
+```
+
+
+## Features
+
+### Remote Desktop Access
+
+Access a full Linux desktop environment in your browser:
+
+- **Window Management:** Run multiple applications with full window controls
+- **Browser Access:** Remote desktop URL for web-based access
+- **Screen Resolution:** Configurable display settings
+- **Clipboard Support:** Copy/paste between local and remote environments
+
+### Pre-installed Applications
+
+The desktop comes with common applications:
+
+
+
+ Firefox, Chromium for browser automation
+
+
+ Text editors, terminals, and dev utilities
+
+
+ Image viewers and basic media players
+
+
+ File managers and system monitors
+
+
+
+## Use Cases
+
+
+
+ Automate web interactions with visual feedback
+
+
+ Test applications requiring GUI in isolated environments
+
+
+ Record application behavior and workflows
+
+
+ Cloud-based development with full desktop access
+
+
+
+## Related Resources
+
+
+
+ Complete walkthrough and examples
+
+
+ Complete API documentation
+
+
+ Customize your desktop environment
+
+
diff --git a/docs/faq.mdx b/docs/faq.mdx
new file mode 100644
index 0000000..15c02a2
--- /dev/null
+++ b/docs/faq.mdx
@@ -0,0 +1,9 @@
+---
+title: "FAQ"
+description: "Frequently asked questions about E2B sandboxes, templates, pricing, security, performance, and common troubleshooting scenarios."
+icon: "circle-question"
+---
+
+# FAQ
+
+Content coming soon.
diff --git a/docs/sandbox/executing-code.mdx b/docs/sandbox/executing-code.mdx
new file mode 100644
index 0000000..9af3719
--- /dev/null
+++ b/docs/sandbox/executing-code.mdx
@@ -0,0 +1,9 @@
+---
+title: "Executing Code"
+description: "Run code and shell commands in E2B sandboxes with support for multiple languages, streaming output, background processes, and real-time execution control."
+icon: "terminal"
+---
+
+# Executing Code
+
+Content coming soon.
diff --git a/docs/sandbox/intro.mdx b/docs/sandbox/intro.mdx
new file mode 100644
index 0000000..c543838
--- /dev/null
+++ b/docs/sandbox/intro.mdx
@@ -0,0 +1,9 @@
+---
+title: "Sandbox Intro"
+description: "E2B sandboxes provide secure, isolated cloud environments for running untrusted code with full control over execution, filesystem, and networking."
+icon: "cube"
+---
+
+# Sandbox Intro
+
+Content coming soon.
diff --git a/docs/sandbox/persistence.mdx b/docs/sandbox/persistence.mdx
index 29f3939..0f4bc88 100644
--- a/docs/sandbox/persistence.mdx
+++ b/docs/sandbox/persistence.mdx
@@ -1,295 +1,9 @@
---
-title: "Sandbox persistence"
-sidebarTitle: Persistence
+title: "Persistence"
+description: "Manage persistent storage in E2B sandboxes with volumes that survive across sandbox sessions, enabling stateful workflows and long-term data retention."
+icon: "database"
---
-
-Sandbox persistence is currently in public beta:
-1. Consider [some limitations](#limitations-while-in-beta).
-2. The persistence is free for all users during the beta.
-
+# Persistence
-The sandbox persistence allows you to pause your sandbox and resume it later from the same state it was in when you paused it.
-
-This includes not only state of the sandbox's filesystem but also the sandbox's memory. This means all running processes, loaded variables, data, etc.
-
-## Sandbox State Transitions
-
-Understanding how sandboxes transition between different states is crucial for managing their lifecycle effectively. Here's a diagram showing the possible state transitions:
-
-
-
-
-
-### State descriptions
-
-- **Running**: The sandbox is actively running and can execute code. This is the initial state after creation.
-- **Paused**: The sandbox execution is suspended but its state is preserved.
-- **Killed**: The sandbox is terminated and all resources are released. This is a terminal state.
-
-### Changing sandbox's state
-
-
-```js JavaScript & TypeScript
-import { Sandbox } from '@e2b/code-interpreter'
-
-const sandbox = await Sandbox.create() // Starts in Running state
-
-// Pause the sandbox
-await sandbox.betaPause() // Running → Paused
-
-// Resume the sandbox
-await sandbox.connect() // Running/Paused → Running
-
-// Kill the sandbox (from any state)
-await sandbox.kill() // Running/Paused → Killed
-```
-
-```python Python
-from e2b_code_interpreter import Sandbox
-
-sandbox = Sandbox.create() # Starts in Running state
-
-# Pause the sandbox
-sandbox.betaPause() # Running → Paused
-
-# Resume the sandbox
-sandbox.connect() # Running/Paused → Running
-
-# Kill the sandbox (from any state)
-sandbox.kill() # Running/Paused → Killed
-```
-
-
-## Pausing sandbox
-When you pause a sandbox, both the sandbox's filesystem and memory state will be saved. This includes all the files in the sandbox's filesystem and all the running processes, loaded variables, data, etc.
-
-
-```js JavaScript & TypeScript highlight={8-9}
-import { Sandbox } from '@e2b/code-interpreter'
-
-const sbx = await Sandbox.create()
-console.log('Sandbox created', sbx.sandboxId)
-
-// Pause the sandbox
-// You can save the sandbox ID in your database to resume the sandbox later
-await sbx.betaPause()
-console.log('Sandbox paused', sbx.sandboxId)
-```
-```python Python highlight={8-9}
-from e2b_code_interpreter import Sandbox
-
-sbx = Sandbox.create()
-print('Sandbox created', sbx.sandbox_id)
-
-# Pause the sandbox
-# You can save the sandbox ID in your database to resume the sandbox later
-sbx.beta_pause()
-print('Sandbox paused', sbx.sandbox_id)
-```
-
-
-
-## Resuming sandbox
-When you resume a sandbox, it will be in the same state it was in when you paused it.
-This means that all the files in the sandbox's filesystem will be restored and all the running processes, loaded variables, data, etc. will be restored.
-
-
-```js JavaScript & TypeScript highlight={12-13}
-import { Sandbox } from '@e2b/code-interpreter'
-
-const sbx = await Sandbox.create()
-console.log('Sandbox created', sbx.sandboxId)
-
-// Pause the sandbox
-// You can save the sandbox ID in your database to resume the sandbox later
-await sbx.betaPause()
-console.log('Sandbox paused', sbx.sandboxId)
-
-// Connect to the sandbox (it will automatically resume the sandbox, if paused)
-const sameSbx = await sbx.connect()
-console.log('Connected to the sandbox', sameSbx.sandboxId)
-```
-```python Python highlight={12-13}
-from e2b_code_interpreter import Sandbox
-
-sbx = Sandbox.create()
-print('Sandbox created', sbx.sandbox_id)
-
-# Pause the sandbox
-# You can save the sandbox ID in your database to resume the sandbox later
-sbx.beta_pause()
-print('Sandbox paused', sbx.sandbox_id)
-
-# Connect to the sandbox (it will automatically resume the sandbox, if paused)
-same_sbx = sbx.connect()
-print('Connected to the sandbox', same_sbx.sandbox_id)
-```
-
-
-## Listing paused sandboxes
-You can list all paused sandboxes by calling the `Sandbox.list` method and supplying the `state` query parameter.
-More information about using the method can be found in [List Sandboxes](/docs/sandbox/list).
-
-
-```js JavaScript & TypeScript highlight={4,7}
-import { Sandbox, SandboxInfo } from '@e2b/code-interpreter'
-
-// List all paused sandboxes
-const paginator = Sandbox.list({ query: { state: ['paused'] } })
-
-// Get the first page of paused sandboxes
-const sandboxes = await paginator.nextItems()
-
-// Get all paused sandboxes
-while (paginator.hasNext) {
- const items = await paginator.nextItems()
- sandboxes.push(...items)
-}
-```
-```python Python highlight={4,7}
-# List all paused sandboxes
-from e2b_code_interpreter import Sandbox, SandboxQuery, SandboxState
-
-paginator = Sandbox.list(SandboxQuery(state=[SandboxState.PAUSED]))
-
-# Get the first page of paused sandboxes
-sandboxes = paginator.next_items()
-
-# Get all paused sandboxes
-while paginator.has_next:
- items = paginator.next_items()
- sandboxes.extend(items)
-```
-
-
-## Removing paused sandboxes
-
-You can remove paused sandboxes by calling the `kill` method on the Sandbox instance.
-
-
-```js JavaScript & TypeScript highlight={11,14}
-import { Sandbox } from '@e2b/code-interpreter'
-
-const sbx = await Sandbox.create()
-console.log('Sandbox created', sbx.sandboxId)
-
-// Pause the sandbox
-// You can save the sandbox ID in your database to resume the sandbox later
-await sbx.betaPause()
-
-// Remove the sandbox
-await sbx.kill()
-
-// Remove sandbox by id
-await Sandbox.kill(sbx.sandboxId)
-```
-```python Python highlight={9,12}
-from e2b_code_interpreter import Sandbox
-
-sbx = Sandbox.create()
-
-# Pause the sandbox
-sbx.beta_pause()
-
-# Remove the sandbox
-sbx.kill()
-
-# Remove sandbox by id
-Sandbox.kill(sbx.sandbox_id)
-```
-
-
-## Sandbox's timeout
-When you connect to a sandbox, the sandbox's timeout is reset to the default timeout of an E2B sandbox - 5 minutes.
-
-You can pass a custom timeout to the `Sandbox.connect()`/`Sandbox.connect()` method like this:
-
-
-```js JavaScript & TypeScript
-import { Sandbox } from '@e2b/code-interpreter'
-
-const sbx = await Sandbox.connect(sandboxId, { timeoutMs: 60 * 1000 }) // 60 seconds
-```
-```python Python
-from e2b_code_interpreter import Sandbox
-
-sbx = Sandbox.connect(sandbox_id, timeout=60) # 60 seconds
-```
-
-
-
-### Auto-pause (beta)
-
-**Note: Auto-pause is currently in beta and available through `Sandbox.betaCreate()`/`Sandbox.beta_create()` method.**
-
-Sandboxes can now automatically pause after they time out. When a sandbox is paused, it stops consuming compute but preserves its state. The default inactivity timeout is 10 minutes. You can change the timeout by passing the `timeoutMs`/`timeout` parameter to the `Sandbox.connect()`/`Sandbox.connect()` method.
-
-
-```js JavaScript & TypeScript
-import { Sandbox } from '@e2b/code-interpreter'
-
-// Create sandbox with auto-pause enabled
-const sandbox = await Sandbox.betaCreate({
- autoPause: true,
- timeoutMs: 10 * 60 * 1000 // Optional: change the default timeout (10 minutes)
-})
-```
-```python Python
-from e2b_code_interpreter import Sandbox
-
-# Create sandbox with auto-pause enabled (Beta)
-sandbox = Sandbox.beta_create(
- auto_pause=True, # Auto-pause after the sandbox times out
- timeout=10 * 60, # Optional: change the default timeout (10 minutes)
-)
-```
-
-
-The auto-pause is persistent, meaning that if your sandbox resumes and it times out, it will be automatically paused again.
-
-If you `.kill()` the sandbox, it will be permanently deleted and you won't be able to resume it.
-
-
-```js JavaScript & TypeScript
-import { Sandbox } from '@e2b/code-interpreter'
-
-// Create sandbox with auto-pause enabled (Beta)
-const sandbox = await Sandbox.betaCreate({
- autoPause: true // Auto-pause after the sandbox times out
-})
-```
-```python Python
-from e2b_code_interpreter import Sandbox
-
-# Create sandbox with auto-pause enabled (Beta)
-sandbox = Sandbox.beta_create(
- auto_pause=True # Auto-pause after the sandbox times out
-)
-```
-
-
-## Network
-If you have a service (for example a server) running inside your sandbox and you pause the sandbox, the service won't be accessible from the outside and all the clients will be disconnected.
-If you resume the sandbox, the service will be accessible again but you need to connect clients again.
-
-
-## Limitations while in beta
-
-### Lifecycle duration
-- A sandbox can exist for **up to 30 days** from the initial `create` call.
-- After 30 days, sandbox data **may be deleted** and the sandbox can no longer be resumed.
-- Attempting to resume a deleted or non-existent sandbox will result in:
- - `NotFoundError` in the JavaScript SDK
- - `NotFoundException` in the Python SDK
-
-### Pause and resume performance
-- Pausing a sandbox takes approximately **4 seconds per 1 GiB of RAM**
-- Resuming a sandbox takes approximately **1 second**
-
-### Continuous runtime limits
-- A sandbox can remain running (without being paused) for:
- - **24 hours** on the **Pro tier**
- - **1 hour** on the **Base tier**
-- After a sandbox is paused and resumed, the continuous runtime limit is **reset**
-- The **30-day total lifetime limit** still applies regardless of how many times the sandbox is paused or resumed
+Content coming soon.
diff --git a/docs/sandbox/reading-output.mdx b/docs/sandbox/reading-output.mdx
new file mode 100644
index 0000000..66e7384
--- /dev/null
+++ b/docs/sandbox/reading-output.mdx
@@ -0,0 +1,9 @@
+---
+title: "Reading Output"
+description: "Capture stdout, stderr, and exit codes from code execution in E2B sandboxes with support for real-time streaming, line-by-line processing, and buffered output handling."
+icon: "scroll"
+---
+
+# Reading Output
+
+Content coming soon.
diff --git a/docs/sandbox/security.mdx b/docs/sandbox/security.mdx
new file mode 100644
index 0000000..50ee389
--- /dev/null
+++ b/docs/sandbox/security.mdx
@@ -0,0 +1,9 @@
+---
+title: "Security"
+description: "Learn about E2B's security model including sandbox isolation, network policies, resource limits, and best practices for running untrusted code safely in production environments."
+icon: "shield-halved"
+---
+
+# Security
+
+Content coming soon.
diff --git a/docs/sdks-explained.mdx b/docs/sdks-explained.mdx
new file mode 100644
index 0000000..8e90fdb
--- /dev/null
+++ b/docs/sdks-explained.mdx
@@ -0,0 +1,228 @@
+---
+title: "SDKs Explained"
+description: "E2B offers three SDK packages, each available in **Python** and **JavaScript/TypeScript**."
+icon: "code"
+---
+
+
+**Architecture:** `e2b-code-interpreter` and `e2b-desktop` are built on top of the core `e2b` SDK. All classes, methods, and features from `e2b` are available in the specialized SDKs.
+
+
+
+
+ Core SDK - Foundation
+
+
+ e2b + code execution environment
+
+
+ e2b + Linux desktop GUI
+
+
+
+---
+
+
+## e2b
+
+General-purpose sandboxes for running any code, commands, or processes.
+
+**Use when:** Building custom AI agents, running untrusted code, or need full control over the environment.
+
+### Installation
+
+
+```bash Python
+pip install e2b
+```
+
+```bash JavaScript
+npm install e2b
+```
+
+
+### Quick Start
+
+
+```python Python
+from e2b import Sandbox
+
+# Create sandbox
+sbx = Sandbox.create()
+
+# Run command
+result = sbx.commands.run("echo 'Hello from E2B'")
+print(result.stdout)
+
+# Run Python code
+result = sbx.commands.run("whoami")
+print(result.stdout)
+```
+
+```typescript JavaScript
+import { Sandbox } from 'e2b'
+
+// Create sandbox
+const sbx = await Sandbox.create()
+
+// Run command
+const result = await sbx.commands.run("echo 'Hello from E2B'")
+console.log(result.stdout)
+
+// Run Node.js code
+const result2 = await sbx.commands.run("whoami")
+console.log(result2.stdout)
+```
+
+
+
+ Complete API documentation
+
+
+---
+
+
+## e2b-code-interpreter
+
+Built on top of `e2b` with added support for multi-language code execution (Python, JavaScript, R, Java, Bash), pre-installed data science libraries, and visualization capabilities.
+
+
+Includes **all features from `e2b`** plus specialized code execution methods and pre-configured environment.
+
+
+**Use when:** Building AI data analysts, code execution environments, or need chart generation.
+
+### Installation
+
+
+```bash Python
+pip install e2b-code-interpreter
+```
+
+```bash JavaScript
+npm install @e2b/code-interpreter
+```
+
+
+### Quick Start
+
+
+```python Python
+from e2b_code_interpreter import Sandbox
+
+# Create code interpreter
+sbx = Sandbox.create()
+
+# Execute code with results
+execution = sbx.run_code("print('Hello from E2B'); 2 + 2")
+
+# Access results
+for result in execution.results:
+ print(result)
+```
+
+```typescript JavaScript
+import { Sandbox } from '@e2b/code-interpreter'
+
+// Create code interpreter
+const sbx = await Sandbox.create()
+
+// Execute code with results
+const execution = await sbx.runCode("console.log('Hello from E2B'); 2 + 2")
+
+// Access results
+execution.results.forEach(result => console.log(result))
+```
+
+
+
+ Detailed documentation, examples, and supported languages
+
+
+---
+
+
+## e2b-desktop
+
+Built on top of `e2b` with a full Linux desktop environment including GUI, browser, and window management.
+
+
+Includes **all features from `e2b`** plus desktop-specific methods like `getDesktopUrl()` and pre-configured GUI environment.
+
+
+**Use when:** Browser automation, visual testing, or applications requiring a desktop UI.
+
+### Installation
+
+
+```bash Python
+pip install e2b-desktop
+```
+
+```bash JavaScript
+npm install @e2b/desktop
+```
+
+
+### Quick Start
+
+
+```python Python
+from e2b_desktop import Sandbox
+
+# Create desktop sandbox
+sbx = Sandbox.create()
+
+# Get desktop URL
+desktop_url = sbx.get_desktop_url()
+print(f"Access desktop at: {desktop_url}")
+
+# Run GUI application
+sbx.commands.run("firefox https://example.com")
+```
+
+```typescript JavaScript
+import { Sandbox } from '@e2b/desktop'
+
+// Create desktop sandbox
+const sbx = await Sandbox.create()
+
+// Get desktop URL
+const desktopUrl = await sbx.getDesktopUrl()
+console.log(`Access desktop at: ${desktopUrl}`)
+
+// Run GUI application
+await sbx.commands.run('firefox https://example.com')
+```
+
+
+
+ Full walkthrough and examples
+
+
+---
+
+## Choosing the Right SDK
+
+
+
+ - Want default Ubuntu VM
+ - Want to use [MCP-Gateway]()
+ - Do not need to use code [interpreter specific functions]()
+
+
+
+ - AI data analysis and visualization
+ - Multi-language code execution (Python, JavaScript, R, Java, Bash)
+ - Need data science libraries pre-installed
+ - Generating charts, plots, or reports
+ - Jupyter-like code execution environment
+
+
+
+ - Browser automation with visual feedback
+ - Testing applications that require a GUI
+ - Screen recording or screenshots
+ - Running desktop applications in the cloud
+
+
diff --git a/docs/templates/intro.mdx b/docs/templates/intro.mdx
new file mode 100644
index 0000000..f6ca82b
--- /dev/null
+++ b/docs/templates/intro.mdx
@@ -0,0 +1,9 @@
+---
+title: "Templates Intro"
+description: "Create custom sandbox templates with pre-installed dependencies, configurations, and tools to quickly spin up consistent development environments for your AI agents."
+icon: "layer-group"
+---
+
+# Templates Intro
+
+Content coming soon.
diff --git a/docs/use-cases/ai-data-analysis-visualization.mdx b/docs/use-cases/ai-data-analysis-visualization.mdx
new file mode 100644
index 0000000..2b885e9
--- /dev/null
+++ b/docs/use-cases/ai-data-analysis-visualization.mdx
@@ -0,0 +1,9 @@
+---
+title: "AI Data Analysis & Visualization"
+description: "Enable AI agents to analyze datasets, generate insights, create charts and visualizations, and perform statistical analysis using Python libraries like pandas, matplotlib, and seaborn."
+icon: "chart-line"
+---
+
+# AI Data Analysis & Visualization
+
+Content coming soon.
diff --git a/docs/use-cases/deep-research-agents.mdx b/docs/use-cases/deep-research-agents.mdx
new file mode 100644
index 0000000..71f5e8e
--- /dev/null
+++ b/docs/use-cases/deep-research-agents.mdx
@@ -0,0 +1,62 @@
+---
+title: "Deep Research Agents"
+description: "Build AI agents that perform comprehensive research by executing code, analyzing data, running experiments, and iterating on findings in isolated sandbox environments."
+icon: "magnifying-glass-chart"
+---
+
+## Related Guides
+
+
+
+ Create and manage E2B sandboxes
+
+
+ Run code in sandboxes
+
+
+ Capture execution results
+
+
+ Save data across sessions
+
+
+ Create charts from findings
+
+
+ Custom sandbox templates
+
+
+
+## Project Structure
+
+
+```ts JavaScript && TypeScript
+research-agent/
+├── agent/
+│ ├── orchestrator.py // Main agent logic
+│ ├── tools.py // Research tools (web search, code execution)
+│ └── memory.py // Research state management
+├── sandbox/
+│ ├── setup.py // Sandbox initialization
+│ └── analysis.py // Data analysis helpers
+├── config.py // Configuration (API keys, models)
+└── main.py // Entry point
+```
+```python Python
+research-agent/
+├── agent/
+│ ├── orchestrator.py # Main agent logic
+│ ├── tools.py # Research tools (web search, code execution)
+│ └── memory.py # Research state management
+├── sandbox/
+│ ├── setup.py # Sandbox initialization
+│ └── analysis.py # Data analysis helpers
+├── config.py # Configuration (API keys, models)
+└── main.py # Entry point
+```
+
+---
+
+## Implementation
+
+Content coming soon.
diff --git a/docs/use-cases/linux-desktop.mdx b/docs/use-cases/linux-desktop.mdx
new file mode 100644
index 0000000..5022b3c
--- /dev/null
+++ b/docs/use-cases/linux-desktop.mdx
@@ -0,0 +1,1156 @@
+---
+title: "AI-Powered Desktop Control"
+description: "Build AI agents that control virtual Linux desktops using OpenAI Computer Use API and E2B Desktop sandboxes with real-time visual feedback."
+icon: "desktop"
+---
+
+## Related Guides
+
+
+
+ Create virtual Linux desktops
+
+
+ Integrate AI models with sandboxes
+
+
+ Customize sandbox environments
+
+
+ Stream execution results in real-time
+
+
+ Manage sandbox files and directories
+
+
+ Configure environment and authentication
+
+
+
+## Project Structure
+
+
+```ts TypeScript
+surf-starter/
+├── app/
+│ ├── api/chat/
+│ │ └── route.ts // SSE endpoint - handles AI loop + sandbox
+│ ├── actions.ts // Server actions for sandbox management
+│ ├── layout.tsx // Root layout with metadata
+│ └── page.tsx // Main UI - chat interface + VNC viewer
+├── lib/
+│ ├── ai/
+│ │ └── instructions.ts // System prompt for AI agent
+│ ├── services/
+│ │ └── openai.ts // Computer use loop with OpenAI
+│ ├── utils/
+│ │ ├── actions.ts // Execute computer actions on sandbox
+│ │ ├── screenshot.ts // Process and resize screenshots
+│ │ └── stream.ts // SSE streaming utilities
+│ ├── constants.ts // Configuration constants
+│ └── env.ts // Environment validation
+├── styles/
+│ └── globals.css // Application styling
+├── types/
+│ └── index.ts // TypeScript types and interfaces
+├── .env // API keys (E2B, OpenAI)
+├── package.json // Dependencies
+└── tsconfig.json // TypeScript configuration
+```
+
+
+---
+
+## How It Works
+
+This application creates an autonomous AI loop that enables natural language control of a virtual Linux desktop:
+
+1. **User Input** - You send a natural language command like "Open Firefox and search for AI news"
+2. **Sandbox Creation** - E2B spins up an Ubuntu 22.04 desktop environment (if not already running)
+3. **Visual Analysis** - The AI receives a screenshot of the current desktop state
+4. **Action Planning** - OpenAI Computer Use API analyzes the screenshot and decides what action to take
+5. **Action Execution** - The action (click, type, scroll, etc.) is executed on the desktop via E2B SDK
+6. **Feedback Loop** - A new screenshot is taken and sent back to the AI
+7. **Iteration** - The loop continues until the task is complete (maximum 15 iterations)
+
+All updates stream to your browser in real-time via Server-Sent Events (SSE), giving you live visibility into what the AI is thinking and doing.
+
+---
+
+## Implementation
+
+### Step 1: Project Setup
+
+Initialize a new Next.js project and install the required dependencies.
+
+
+
+ ```bash
+ npx create-next-app@latest surf-starter --typescript --app --no-tailwind
+ cd surf-starter
+ ```
+
+
+
+ ```bash
+ npm install @e2b/desktop openai sharp
+ ```
+
+ **Dependencies explained:**
+ - `@e2b/desktop` - E2B Desktop SDK for controlling virtual Linux desktops
+ - `openai` - OpenAI SDK for Computer Use API integration
+ - `sharp` - Fast image processing library for screenshot optimization
+
+
+
+### Step 2: Environment Configuration
+
+Set up your API keys and create environment validation utilities.
+
+
+
+ Create a `.env` file in your project root:
+
+ ```env
+ E2B_API_KEY=your_e2b_api_key_here
+ OPENAI_API_KEY=your_openai_api_key_here
+ ```
+
+ Get your API keys:
+ - E2B API Key: [https://e2b.dev/docs/api-key](https://e2b.dev/docs/api-key)
+ - OpenAI API Key: [https://platform.openai.com/api-keys](https://platform.openai.com/api-keys)
+
+
+
+ Create `lib/env.ts` to validate environment variables:
+
+ ```typescript
+ // lib/env.ts
+ export function getEnv() {
+ const E2B_API_KEY = process.env.E2B_API_KEY;
+ const OPENAI_API_KEY = process.env.OPENAI_API_KEY;
+
+ if (!E2B_API_KEY || !OPENAI_API_KEY) {
+ throw new Error('Missing required environment variables');
+ }
+
+ return { E2B_API_KEY, OPENAI_API_KEY };
+ }
+
+ export function isEnvironmentConfigured(): boolean {
+ return !!(process.env.E2B_API_KEY && process.env.OPENAI_API_KEY);
+ }
+ ```
+
+
+
+### Step 3: Type Definitions
+
+Define TypeScript interfaces for type safety throughout the application.
+
+
+
+ Create `types/index.ts` with core application types:
+
+ ```typescript
+ // types/index.ts
+
+ // Message structure for chat interface
+ export interface ChatMessage {
+ role: 'user' | 'assistant' | 'system' | 'action';
+ content: string;
+ }
+
+ // Computer actions the AI can execute
+ export type ComputerAction =
+ | { type: 'click'; x: number; y: number; button: 'left' | 'right' | 'wheel' }
+ | { type: 'double_click'; x: number; y: number }
+ | { type: 'type'; text: string }
+ | { type: 'key' | 'keypress'; keys?: string[]; key?: string }
+ | { type: 'move'; x: number; y: number }
+ | { type: 'drag'; start_x: number; start_y: number; x: number; y: number }
+ | { type: 'scroll'; amount: number }
+ | { type: 'wait'; duration?: number }
+ | { type: 'screenshot' };
+
+ // SSE events for real-time updates
+ export interface SSEEvent {
+ type: 'sandbox_created' | 'reasoning' | 'action' | 'action_completed' | 'done' | 'error';
+ content?: string;
+ action?: string;
+ sandboxId?: string;
+ url?: string;
+ message?: string;
+ }
+
+ // Conversation tracking for context
+ export interface ConversationTurn {
+ userMessage: string;
+ aiResponse: string;
+ timestamp: number;
+ }
+ ```
+
+ The `ComputerAction` discriminated union ensures type-safe action handling throughout the application.
+
+
+
+### Step 4: Configuration Constants
+
+Centralize all configuration values for easy management.
+
+
+
+ Create `lib/constants.ts` with application-wide constants:
+
+ ```typescript
+ // lib/constants.ts
+
+ // Sandbox configuration
+ export const SANDBOX_CONFIG = {
+ TIMEOUT_MS: 300_000, // 5 minutes initial timeout
+ TIMEOUT_SECONDS: 300,
+ AUTO_EXTEND_THRESHOLD: 10,
+ ACTIVE_WORK_TIMEOUT_MS: 600_000, // 10 minutes during active work
+ MIN_EXTEND_INTERVAL_MS: 30_000, // Minimum 30s between extensions
+ } as const;
+
+ // Screenshot processing
+ export const SCREENSHOT_CONFIG = {
+ MAX_WIDTH: 1024,
+ MAX_HEIGHT: 768,
+ MIN_WIDTH: 640,
+ MIN_HEIGHT: 480,
+ } as const;
+
+ // AI model configuration
+ export const AI_CONFIG = {
+ MODEL: 'computer-use-preview', // OpenAI computer use model
+ MAX_ITERATIONS: 15, // Maximum loop iterations
+ MAX_WAIT_DURATION: 1500, // Maximum wait time (ms)
+ REASONING_EFFORT: 'medium', // AI reasoning level
+ } as const;
+
+ // API configuration
+ export const API_CONFIG = {
+ MAX_DURATION: 300, // 5 minutes per request
+ RUNTIME: 'nodejs',
+ } as const;
+ ```
+
+ These constants make it easy to adjust timeouts, screenshot sizes, and AI behavior without hunting through code.
+
+
+
+### Step 5: Utility Functions
+
+Build helper functions for screenshot processing, streaming, and action execution.
+
+
+
+ Create `lib/utils/screenshot.ts` to optimize screenshots:
+
+ ```typescript
+ // lib/utils/screenshot.ts
+ import sharp from 'sharp';
+ import { SCREENSHOT_CONFIG } from '@/lib/constants';
+
+ export async function processScreenshot(
+ screenshotBuffer: Uint8Array | Buffer
+ ): Promise {
+ const processedBuffer = await sharp(screenshotBuffer)
+ .resize(SCREENSHOT_CONFIG.MAX_WIDTH, SCREENSHOT_CONFIG.MAX_HEIGHT, {
+ fit: 'contain',
+ background: { r: 0, g: 0, b: 0, alpha: 1 },
+ })
+ .png()
+ .toBuffer();
+
+ return processedBuffer.toString('base64');
+ }
+ ```
+
+ This function resizes screenshots to optimal dimensions and converts them to base64 for API transmission.
+
+
+
+ Create `lib/utils/stream.ts` for SSE streaming:
+
+ ```typescript
+ // lib/utils/stream.ts
+ export function createSafeStreamController(
+ controller: ReadableStreamDefaultController
+ ) {
+ let isControllerClosed = false;
+
+ const safeEnqueue = (data: Uint8Array): void => {
+ if (!isControllerClosed) {
+ try {
+ controller.enqueue(data);
+ } catch (error) {
+ isControllerClosed = true;
+ }
+ }
+ };
+
+ const safeClose = (): void => {
+ if (!isControllerClosed) {
+ try {
+ controller.close();
+ isControllerClosed = true;
+ } catch (error) {
+ isControllerClosed = true;
+ }
+ }
+ };
+
+ return { enqueue: safeEnqueue, close: safeClose };
+ }
+
+ export function createSSEEvent(event: object): string {
+ return `data: ${JSON.stringify(event)}\n\n`;
+ }
+ ```
+
+ The safe stream controller prevents "already closed" errors during SSE streaming.
+
+
+
+ Create `lib/utils/actions.ts` to map AI actions to E2B SDK calls:
+
+ ```typescript
+ // lib/utils/actions.ts
+ import type { Sandbox } from '@e2b/desktop';
+ import type { ComputerAction } from '@/types';
+
+ export async function executeComputerAction(
+ sandbox: Sandbox,
+ action: ComputerAction
+ ): Promise {
+ switch (action.type) {
+ case 'click':
+ if (action.button === 'left') {
+ await sandbox.leftClick(action.x, action.y);
+ } else if (action.button === 'right') {
+ await sandbox.rightClick(action.x, action.y);
+ }
+ break;
+
+ case 'double_click':
+ await sandbox.doubleClick(action.x, action.y);
+ break;
+
+ case 'type':
+ await sandbox.write(action.text);
+ break;
+
+ case 'key':
+ case 'keypress':
+ const key = action.keys?.[0] || action.key;
+ if (key) await sandbox.press(key);
+ break;
+
+ case 'move':
+ await sandbox.moveMouse(action.x, action.y);
+ break;
+
+ case 'scroll':
+ await sandbox.scroll(action.amount < 0 ? 'up' : 'down');
+ break;
+
+ case 'wait':
+ await new Promise(resolve =>
+ setTimeout(resolve, Math.min(action.duration || 1000, 3000))
+ );
+ break;
+ }
+ }
+
+ export function formatActionForDisplay(action: ComputerAction): string {
+ switch (action.type) {
+ case 'click':
+ return `Click ${action.button} at (${action.x}, ${action.y})`;
+ case 'type':
+ return `Type: "${action.text}"`;
+ case 'key':
+ case 'keypress':
+ return `Press key: ${action.keys?.[0] || action.key}`;
+ default:
+ return `Action: ${action.type}`;
+ }
+ }
+ ```
+
+ This utility translates OpenAI Computer Use actions into E2B Desktop SDK method calls.
+
+
+
+### Step 6: AI System Prompt
+
+Define the system instructions that guide the AI agent's behavior.
+
+
+
+ Create `lib/ai/instructions.ts` with the AI agent prompt:
+
+ ```typescript
+ // lib/ai/instructions.ts
+ export const SYSTEM_INSTRUCTIONS = `You are Surf, an AI assistant that controls a Linux desktop to help users with tasks.
+
+ENVIRONMENT:
+- Ubuntu 22.04 desktop with Firefox, VS Code, LibreOffice, Terminal, File Manager, Text Editor
+- Desktop has bottom taskbar with application launchers
+- Desktop is ready - you can start immediately
+
+AVAILABLE ACTIONS:
+- screenshot: View current desktop state
+- click/double_click: Click at coordinates (left/right/middle button)
+- type: Type text into focused field
+- key: Press keyboard keys (ENTER, ESCAPE, TAB, BACKSPACE, etc.)
+- move: Move mouse cursor
+- drag: Drag between two positions
+- scroll: Scroll up or down
+- wait: Pause briefly (use only after opening apps or loading pages)
+
+EXECUTION GUIDELINES:
+1. Take screenshots to see the current state
+2. Identify UI elements using coordinates from screenshots
+3. Execute actions precisely
+4. After opening applications or loading pages, wait 1-2 seconds for them to load
+5. After terminal commands, press ENTER to execute
+6. Complete tasks efficiently with minimal delays
+
+AUTONOMY:
+- Execute tasks directly when intent is clear
+- Ask clarifying questions only when there's genuine ambiguity
+- When user confirms ("yes", "proceed", "do it"), take the next action immediately
+
+COMPLETION:
+- When done, explain what you accomplished
+- Stop taking actions once the goal is achieved
+
+Be helpful, precise, and efficient.`;
+ ```
+
+ This prompt is crucial for effective agent behavior. It teaches the AI about the environment, available actions, and expected execution patterns.
+
+
+
+### Step 7: Computer Use Loop
+
+Implement the core AI execution loop that powers desktop control.
+
+
+
+ Create `lib/services/openai.ts` with the computer use loop:
+
+ ```typescript
+ // lib/services/openai.ts
+ import OpenAI from 'openai';
+ import type { Sandbox } from '@e2b/desktop';
+ import { AI_CONFIG, SCREENSHOT_CONFIG } from '@/lib/constants';
+ import { SYSTEM_INSTRUCTIONS } from '@/lib/ai/instructions';
+ import { processScreenshot } from '@/lib/utils/screenshot';
+ import { executeComputerAction, formatActionForDisplay } from '@/lib/utils/actions';
+ import { getEnv } from '@/lib/env';
+
+ export async function runComputerUseLoop(
+ sandbox: Sandbox,
+ userMessage: string,
+ sendEvent: (data: Uint8Array) => void
+ ): Promise {
+ const { OPENAI_API_KEY } = getEnv();
+ const openai = new OpenAI({ apiKey: OPENAI_API_KEY });
+ const encoder = new TextEncoder();
+
+ // Take initial screenshot
+ const screenshotBuffer = await sandbox.screenshot();
+ const screenshotBase64 = await processScreenshot(screenshotBuffer);
+
+ // Define computer tool
+ const computerTool = {
+ type: 'computer_use_preview' as const,
+ display_width: SCREENSHOT_CONFIG.MAX_WIDTH,
+ display_height: SCREENSHOT_CONFIG.MAX_HEIGHT,
+ environment: 'linux' as const,
+ };
+
+ // Create initial request with screenshot
+ let response = await openai.responses.create({
+ model: AI_CONFIG.MODEL,
+ tools: [computerTool],
+ input: [{
+ type: 'message',
+ role: 'user',
+ content: [
+ { type: 'input_text', text: userMessage },
+ { type: 'input_image', image_url: `data:image/png;base64,${screenshotBase64}`, detail: 'high' },
+ ],
+ }],
+ instructions: SYSTEM_INSTRUCTIONS,
+ truncation: 'auto',
+ reasoning: { effort: AI_CONFIG.REASONING_EFFORT, generate_summary: 'concise' },
+ });
+
+ let iterations = 0;
+
+ // Main execution loop
+ while (iterations < AI_CONFIG.MAX_ITERATIONS) {
+ iterations++;
+
+ // Extract computer actions from AI response
+ const computerCalls = response.output.filter(
+ (item: any) => item.type === 'computer_call'
+ );
+
+ // If no actions, task is complete
+ if (computerCalls.length === 0) {
+ sendEvent(encoder.encode(`data: ${JSON.stringify({
+ type: 'reasoning',
+ content: response.output_text || 'Task complete!'
+ })}\n\n`));
+ break;
+ }
+
+ const computerCall = computerCalls[0] as any;
+ const action = computerCall.action;
+
+ // Send action to client
+ sendEvent(encoder.encode(`data: ${JSON.stringify({
+ type: 'action',
+ action: formatActionForDisplay(action)
+ })}\n\n`));
+
+ // Execute action on sandbox
+ await executeComputerAction(sandbox, action);
+
+ sendEvent(encoder.encode(`data: ${JSON.stringify({
+ type: 'action_completed'
+ })}\n\n`));
+
+ // Take new screenshot
+ const newScreenshotBuffer = await sandbox.screenshot();
+ const newScreenshotBase64 = await processScreenshot(newScreenshotBuffer);
+
+ // Continue conversation with new screenshot
+ response = await openai.responses.create({
+ model: AI_CONFIG.MODEL,
+ previous_response_id: response.id,
+ instructions: SYSTEM_INSTRUCTIONS,
+ tools: [computerTool],
+ input: [{
+ call_id: computerCall.call_id,
+ type: 'computer_call_output',
+ output: {
+ type: 'computer_screenshot',
+ image_url: `data:image/png;base64,${newScreenshotBase64}`,
+ },
+ }],
+ truncation: 'auto',
+ reasoning: { effort: AI_CONFIG.REASONING_EFFORT, generate_summary: 'concise' },
+ });
+ }
+ }
+ ```
+
+ This is the heart of the application. The loop continuously:
+ 1. Takes screenshots of the desktop
+ 2. Sends them to OpenAI with context
+ 3. Receives structured computer actions
+ 4. Executes actions via E2B
+ 5. Repeats until the task is complete
+
+
+
+### Step 8: API Endpoint
+
+Create the backend API endpoint that orchestrates sandbox creation and AI execution.
+
+
+
+ Create `app/api/chat/route.ts` for the SSE streaming endpoint:
+
+ ```typescript
+ // app/api/chat/route.ts
+ import { Sandbox } from '@e2b/desktop';
+ import { NextRequest } from 'next/server';
+ import { getEnv, isEnvironmentConfigured } from '@/lib/env';
+ import { SANDBOX_CONFIG } from '@/lib/constants';
+ import { createSafeStreamController, createSSEEvent } from '@/lib/utils/stream';
+ import { runComputerUseLoop } from '@/lib/services/openai';
+
+ // In-memory store for active sandboxes
+ const sandboxes = new Map();
+
+ export async function POST(req: NextRequest) {
+ try {
+ const { message, sandboxId } = await req.json();
+
+ if (!message) {
+ return new Response(JSON.stringify({ error: 'Message required' }), { status: 400 });
+ }
+
+ if (!isEnvironmentConfigured()) {
+ return new Response(createSSEEvent({ type: 'error', message: 'Missing API keys' }), {
+ headers: { 'Content-Type': 'text/event-stream' },
+ });
+ }
+
+ const { E2B_API_KEY } = getEnv();
+ const encoder = new TextEncoder();
+
+ // Create SSE stream
+ const stream = new ReadableStream({
+ async start(controller) {
+ const safeController = createSafeStreamController(controller);
+
+ try {
+ // Reuse existing sandbox or create new one
+ let sandbox = sandboxId ? sandboxes.get(sandboxId) : null;
+
+ if (!sandbox) {
+ safeController.enqueue(encoder.encode(createSSEEvent({
+ type: 'reasoning',
+ content: 'Creating sandbox...',
+ })));
+
+ sandbox = await Sandbox.create({
+ apiKey: E2B_API_KEY,
+ timeoutMs: SANDBOX_CONFIG.TIMEOUT_MS,
+ });
+
+ await sandbox.stream.start();
+ sandboxes.set(sandbox.sandboxId, sandbox);
+
+ safeController.enqueue(encoder.encode(createSSEEvent({
+ type: 'sandbox_created',
+ sandboxId: sandbox.sandboxId,
+ url: sandbox.stream.getUrl(),
+ })));
+ } else {
+ await sandbox.setTimeout(SANDBOX_CONFIG.TIMEOUT_MS);
+ }
+
+ // Run the AI loop
+ await runComputerUseLoop(sandbox, message, safeController.enqueue);
+
+ safeController.enqueue(encoder.encode(createSSEEvent({ type: 'done' })));
+ safeController.close();
+ } catch (error) {
+ safeController.enqueue(encoder.encode(createSSEEvent({
+ type: 'error',
+ message: error instanceof Error ? error.message : 'Unknown error',
+ })));
+ safeController.close();
+ }
+ },
+ });
+
+ return new Response(stream, {
+ headers: {
+ 'Content-Type': 'text/event-stream',
+ 'Cache-Control': 'no-cache',
+ 'Connection': 'keep-alive',
+ },
+ });
+ } catch (error) {
+ return new Response(
+ JSON.stringify({ error: error instanceof Error ? error.message : 'Internal error' }),
+ { status: 500 }
+ );
+ }
+ }
+
+ export const runtime = 'nodejs';
+ export const maxDuration = 300;
+ ```
+
+ The endpoint:
+ - Validates environment and request
+ - Creates or reuses E2B sandboxes
+ - Starts VNC streaming
+ - Runs the computer use loop
+ - Streams events back to the client in real-time
+
+
+
+### Step 9: Server Actions
+
+Add Next.js server actions for sandbox management from the client.
+
+
+
+ Create `app/actions.ts` for server-side operations:
+
+ ```typescript
+ // app/actions.ts
+ 'use server';
+
+ import { Sandbox } from '@e2b/desktop';
+ import { getEnv } from '@/lib/env';
+ import { SANDBOX_CONFIG } from '@/lib/constants';
+
+ export async function extendSandboxTimeout(sandboxId: string) {
+ try {
+ if (!sandboxId) {
+ return { success: false, error: 'Sandbox ID required' };
+ }
+
+ const { E2B_API_KEY } = getEnv();
+ const sandbox = await Sandbox.connect(sandboxId, { apiKey: E2B_API_KEY });
+ await sandbox.setTimeout(SANDBOX_CONFIG.TIMEOUT_MS);
+
+ return { success: true };
+ } catch (error) {
+ return {
+ success: false,
+ error: error instanceof Error ? error.message : 'Unknown error',
+ };
+ }
+ }
+
+ export async function stopSandbox(sandboxId: string) {
+ try {
+ if (!sandboxId) {
+ return { success: false, error: 'Sandbox ID required' };
+ }
+
+ const { E2B_API_KEY } = getEnv();
+ const sandbox = await Sandbox.connect(sandboxId, { apiKey: E2B_API_KEY });
+ await sandbox.kill();
+
+ return { success: true };
+ } catch (error) {
+ return {
+ success: false,
+ error: error instanceof Error ? error.message : 'Unknown error',
+ };
+ }
+ }
+ ```
+
+ These server actions allow the client to:
+ - **Extend timeout**: Add 5 more minutes to prevent sandbox from expiring
+ - **Stop sandbox**: Immediately terminate and clean up resources
+
+
+
+### Step 10: Chat Interface
+
+Build the React frontend with sophisticated UI, status tracking, and real-time event handling.
+
+
+
+ Create `app/page.tsx` with the full-featured interface. This is a comprehensive implementation with status tracking, timeout management, and conversation history. See the surf-starter_olddd directory for the complete 422-line implementation.
+
+ **Key features implemented:**
+ - Real-time status bar showing AI activity (thinking, executing, etc.)
+ - Countdown timer with color-coded urgency (green → yellow → red)
+ - Automatic timeout extension during active work
+ - Conversation history tracking for multi-turn context
+ - Welcome message with example prompts
+ - Typing indicators with animated dots
+ - Action pills for executed commands
+ - Sandbox status badge with pulsing animation
+ - Auto-scrolling to latest messages
+ - Comprehensive error handling
+
+ **The implementation includes:**
+ - Header with gradient "🏄 Surf Demo" title
+ - Status bar that slides down when active
+ - Desktop viewer with floating timeout overlay
+ - Chat container with header, messages area, and input form
+ - Multiple state hooks for managing UI, sandbox, and conversation
+ - SSE event parsing with buffer handling
+ - Formatted time display (MM:SS)
+ - Color transitions based on time remaining
+
+ Refer to `/surf-starter_olddd/app/page.tsx` for the complete 422-line implementation with all handlers and UI logic.
+
+
+
+### Step 11: Desktop Viewer
+
+The desktop viewer includes a sophisticated timeout overlay with visual feedback.
+
+
+
+ The desktop viewer features:
+ - **VNC iframe**: Live desktop stream from E2B (`sandbox.stream.getUrl()`)
+ - **Timeout overlay**: Floating widget positioned absolutely at top-right
+ - **Progress bar**: Visual countdown with smooth color transitions
+ - **Control buttons**: "+5 min" extend button and "⏹️" stop button
+ - **Placeholder state**: Helpful message with example prompt when no sandbox exists
+ - **Backdrop blur**: Glassmorphism effect on the timeout overlay
+
+ The overlay sits on top of the iframe using `position: absolute` with `z-index: 10` and uses `backdrop-filter: blur(8px)` for a modern glass effect.
+
+
+
+### Step 12: Styling
+
+Create a polished, professional interface with E2B branding and smooth animations.
+
+
+
+ Create `styles/globals.css` with the complete 606-line styling. Key features:
+
+ **Typography & Theme:**
+ ```css
+ @import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;500;600;700&family=IBM+Plex+Mono:wght@400;500;600&display=swap');
+
+ :root {
+ --e2b-orange: hsl(32 100% 50%);
+ --e2b-orange-dark: hsl(32 100% 45%);
+ --e2b-orange-light: hsl(32 95% 55%);
+ --e2b-bg: hsl(0 0% 7%);
+ --e2b-bg-elevated: hsl(0 0% 10%);
+ --e2b-border: hsl(0 0% 15%);
+ --e2b-text: hsl(0 0% 98%);
+ --e2b-text-muted: hsl(0 0% 70%);
+ }
+ ```
+
+ **Key Animations:**
+ - `slideDown`: Status bar entrance animation
+ - `spin`: Loading spinner rotation
+ - `pulse`: Sandbox badge dot pulsing
+ - `fadeIn`: Message appearance with slide up
+ - `bounce`: Typing indicator dots
+
+ **Major Components:**
+ - **Header**: 3em gradient title with orange-to-light gradient
+ - **Status Bar**: Elevated background with animated spinner
+ - **Desktop View**: 2fr grid column with shadow and rounded corners
+ - **Timeout Overlay**: Dark translucent with backdrop blur
+ - **Chat Container**: 1fr grid column with header, messages, input
+ - **Messages**: Flex column with role-based colors and styles
+ - **Welcome Message**: Orange-bordered info panel with examples
+ - **Action Pills**: Rounded orange badges for executed actions
+ - **Typing Indicator**: Three bouncing dots with staggered animation
+ - **Send Button**: Orange with hover lift effect and shadow
+
+ **Responsive Grid:**
+ ```css
+ main {
+ display: grid;
+ grid-template-columns: 2fr 1fr;
+ gap: 20px;
+ height: calc(100vh - 220px);
+ }
+ ```
+
+ **Custom Scrollbar:**
+ ```css
+ .messages::-webkit-scrollbar {
+ width: 8px;
+ }
+ .messages::-webkit-scrollbar-thumb {
+ background: var(--e2b-border);
+ border-radius: 4px;
+ }
+ .messages::-webkit-scrollbar-thumb:hover {
+ background: rgba(255, 140, 0, 0.5);
+ }
+ ```
+
+ The complete 606-line stylesheet is available in `/surf-starter_olddd/styles/globals.css` with all animations, hover states, and responsive breakpoints.
+
+
+
+### Step 13: Running the Application
+
+Start the development server and test your AI desktop control application.
+
+
+
+ ```bash
+ npm run dev
+ ```
+
+ Visit [http://localhost:3000](http://localhost:3000) in your browser.
+
+
+
+ Try these commands to test the application:
+
+ - "Open Firefox and search for E2B documentation"
+ - "Open VS Code and create a new file called hello.py"
+ - "Open Terminal and run 'ls -la'"
+ - "Take a screenshot of the desktop"
+ - "Open File Manager and navigate to the Documents folder"
+
+ **What to expect:**
+ 1. Sandbox creation (takes 5-10 seconds on first request)
+ 2. VNC desktop viewer appears showing Ubuntu desktop
+ 3. AI reasoning messages appear in chat
+ 4. Actions execute in real-time on the desktop
+ 5. You see live feedback of mouse clicks, typing, and application launches
+
+
+
+ When ready to deploy:
+
+ ```bash
+ npm run build
+ npm start
+ ```
+
+ Deploy to platforms like Vercel, Railway, or any Node.js hosting provider. Make sure to set environment variables in your deployment platform.
+
+
+
+---
+
+## Key Concepts
+
+### E2B Desktop Sandbox
+An isolated Ubuntu 22.04 environment running in the cloud:
+- **Pre-installed apps**: Firefox, VS Code, LibreOffice, Terminal, File Manager, Text Editor
+- **VNC access**: Real-time desktop streaming via iframe
+- **Resolution**: 1024x768 by default (configurable)
+- **Ephemeral**: Each sandbox is temporary unless you configure persistent storage
+- **On-demand**: Created in seconds, destroyed automatically after timeout
+
+### OpenAI Computer Use API
+A vision-enabled AI model that can control computers:
+- **Vision capabilities**: Analyzes desktop screenshots to understand UI state
+- **Structured actions**: Returns computer actions like click, type, scroll
+- **Reasoning**: Uses chain-of-thought to plan multi-step tasks
+- **Context preservation**: Maintains conversation history across actions
+- **Model**: Uses `computer-use-preview` model optimized for GUI interaction
+
+### Computer Actions
+The AI can execute these actions on the desktop:
+
+| Action | Parameters | E2B SDK Method | Purpose |
+|--------|-----------|----------------|---------|
+| `click` | x, y, button | `sandbox.leftClick()`, `sandbox.rightClick()` | Click at coordinates |
+| `double_click` | x, y | `sandbox.doubleClick()` | Double-click at position |
+| `type` | text | `sandbox.write()` | Type text into focused field |
+| `key` | key name | `sandbox.press()` | Press keyboard keys (ENTER, ESC, etc.) |
+| `move` | x, y | `sandbox.moveMouse()` | Move cursor without clicking |
+| `drag` | start_x, start_y, x, y | `sandbox.drag()` | Drag between positions |
+| `scroll` | amount | `sandbox.scroll()` | Scroll up or down |
+| `wait` | duration (ms) | `setTimeout()` | Pause for UI to load |
+
+### Streaming Architecture
+Real-time updates using Server-Sent Events (SSE):
+
+- **Event types**:
+ - `sandbox_created` - New sandbox initialized with VNC URL
+ - `reasoning` - AI thinking/planning message
+ - `action` - About to execute action
+ - `action_completed` - Action finished successfully
+ - `done` - Task complete
+ - `error` - Error occurred
+
+- **Benefits**:
+ - Live progress visibility
+ - Responsive user experience
+ - Works over standard HTTP (no WebSocket needed)
+ - Automatic reconnection in modern browsers
+
+---
+
+## Best Practices
+
+### Prompt Engineering
+- **Be specific**: "Open Firefox and go to github.com" is better than "Open a browser"
+- **Use action verbs**: "Click the Submit button" rather than "I want to submit"
+- **Mention UI elements**: Reference specific buttons, fields, or menu items
+- **Break down complex tasks**: Give the AI clear steps for multi-part operations
+
+### Performance Optimization
+- **Reuse sandboxes**: Keep sandbox alive across multiple related tasks to avoid creation overhead
+- **Extend timeouts proactively**: Use the +5 min button before timeout expires
+- **Optimize screenshots**: Balance resolution with API cost (1024x768 is a good default)
+- **Set reasonable iteration limits**: 15 iterations handles most tasks; increase only if needed
+
+### Security Considerations
+- **Never commit API keys**: Always use environment variables
+- **Validate user input**: Sanitize input before sending to AI to prevent prompt injection
+- **Use environment variables**: Store all secrets in `.env` files (not in code)
+- **Rate limiting**: In production, add rate limits to prevent API abuse
+- **Sandbox isolation**: E2B sandboxes are isolated - they can't access your local machine
+
+### Production Readiness
+- **Persistent storage**: Store sandbox IDs in Redis or database instead of in-memory Map
+- **Authentication**: Add user authentication (NextAuth, Clerk, etc.)
+- **Error boundaries**: Implement React error boundaries for graceful failure handling
+- **Logging**: Add structured logging for debugging and monitoring
+- **Cost monitoring**: Track E2B and OpenAI API usage to control costs
+- **Webhooks**: Use E2B webhooks to track sandbox lifecycle events
+
+---
+
+## Troubleshooting
+
+### Sandbox Not Appearing
+
+**Problem**: Desktop viewer doesn't show or sandbox creation fails
+
+**Solutions**:
+- Verify both `E2B_API_KEY` and `OPENAI_API_KEY` are set in `.env`
+- Check E2B dashboard to ensure you have available credits
+- Open browser DevTools Console and check for errors
+- Review server terminal logs for backend errors
+- Ensure you're using Node.js 18 or higher
+
+### AI Not Taking Actions
+
+**Problem**: AI responds but doesn't execute computer actions
+
+**Solutions**:
+- Confirm you have access to OpenAI's `computer-use-preview` model
+- Try more specific instructions with clear action verbs
+- Ensure desktop has fully loaded before issuing commands
+- Check if `MAX_ITERATIONS` limit was reached (increase if needed)
+- Review AI reasoning messages to understand its decision-making
+
+### Actions Failing
+
+**Problem**: Actions execute but don't work as expected
+
+**Solutions**:
+- **Wait times**: Applications need time to load - AI should use `wait` action after opening apps
+- **Coordinates**: Click actions depend on 1024x768 resolution - ensure screenshots match
+- **Keyboard keys**: Use standard key names from E2B docs (e.g., "Return" not "Enter")
+- **UI timing**: Some UI elements appear after animation - add appropriate waits
+- **Focus issues**: Ensure input fields are focused before typing
+
+### Timeout Issues
+
+**Problem**: Sandbox expires during long tasks
+
+**Solutions**:
+- Server automatically extends timeout to 10 minutes during active AI work
+- Use the manual "+5 min" button before timeout expires
+- Increase `ACTIVE_WORK_TIMEOUT_MS` in constants for longer tasks
+- Monitor timeout countdown in UI
+- Consider breaking very long tasks into smaller steps
+
+### SSE Connection Problems
+
+**Problem**: Events stop streaming or connection drops
+
+**Solutions**:
+- Check network connectivity and firewall settings
+- Verify SSE headers are correctly set (Content-Type: text/event-stream)
+- Ensure safe stream controller is being used to prevent double-close errors
+- Review browser console for SSE-related errors
+- Test with a simple SSE client to isolate frontend vs backend issues
+
+---
+
+## Next Steps
+
+
+
+ Add support for Anthropic Claude or Google Gemini with computer use capabilities
+
+
+ Pre-install specific software or configure the desktop environment for your use case
+
+
+ Add file upload/download, implement clipboard operations, and export screenshots
+
+
+ Add authentication, database persistence, monitoring, and deploy to cloud platforms
+
+
+ Implement session management, sandbox pooling, and user isolation for SaaS applications
+
+
+ Optimize screenshot compression, implement caching, and choose cost-effective AI models
+
+
+ Extend with custom tools, web scraping, data extraction, and complex workflows
+
+
+ Track usage patterns, measure task success rates, and optimize agent performance
+
+
+
+---
+
+## Build the Complete Project
+
+Now that you understand how everything works, you can build and run the complete working application from the `surf-starter_olddd` directory.
+
+
+
+ ```bash
+ cd surf-starter_olddd
+ ```
+
+
+
+ ```bash
+ npm install
+ ```
+
+ This installs all required packages including:
+ - `@e2b/desktop` - E2B Desktop SDK
+ - `openai` - OpenAI SDK
+ - `sharp` - Image processing
+ - `next` - Next.js framework
+ - `react` & `react-dom` - React libraries
+
+
+
+ Copy the example environment file and add your API keys:
+
+ ```bash
+ cp .env.example .env
+ ```
+
+ Edit the `.env` file with your actual API keys:
+
+ ```env
+ E2B_API_KEY=your_e2b_api_key_here
+ OPENAI_API_KEY=your_openai_api_key_here
+ ```
+
+ **Get your API keys:**
+ - E2B API Key: [https://e2b.dev/docs/api-key](https://e2b.dev/docs/api-key)
+ - OpenAI API Key: [https://platform.openai.com/api-keys](https://platform.openai.com/api-keys)
+
+
+
+ Start the application in development mode:
+
+ ```bash
+ npm run dev
+ ```
+
+ Open [http://localhost:3000](http://localhost:3000) in your browser to see the live application.
+
+ **Try these example prompts:**
+ - "Open Firefox and search for E2B documentation"
+ - "Open VS Code and create a new file"
+ - "Open Terminal and run 'ls -la'"
+ - "Take a screenshot of the desktop"
+
+
+
+ When ready to deploy, create a production build:
+
+ ```bash
+ npm run build
+ npm start
+ ```
+
+ Deploy to platforms like Vercel, Railway, or any Node.js hosting provider. Make sure to configure environment variables in your deployment platform's settings.
+
+
+
+### What You'll See
+
+1. **Sandbox Creation** - Takes 5-10 seconds on first request
+2. **Desktop Viewer** - Live VNC stream showing Ubuntu desktop
+3. **AI Reasoning** - Real-time messages showing AI's thought process
+4. **Action Execution** - Watch as the AI clicks, types, and navigates the desktop
+5. **Timeout Management** - Use the "+5 min" button to extend session time
+
+The complete source code is in the [surf-starter_olddd](../surf-starter_olddd/) directory with all files discussed in this guide.
diff --git a/docs/use-cases/reinforcement-learning.mdx b/docs/use-cases/reinforcement-learning.mdx
new file mode 100644
index 0000000..8040ebd
--- /dev/null
+++ b/docs/use-cases/reinforcement-learning.mdx
@@ -0,0 +1,9 @@
+---
+title: "Reinforcement Learning"
+description: "Train and evaluate reinforcement learning agents in secure sandbox environments with support for simulation frameworks, custom environments, and parallel training workflows."
+icon: "brain-circuit"
+---
+
+# Reinforcement Learning
+
+Content coming soon.
diff --git a/docs/use-cases/vibe-coding.mdx b/docs/use-cases/vibe-coding.mdx
new file mode 100644
index 0000000..363fb86
--- /dev/null
+++ b/docs/use-cases/vibe-coding.mdx
@@ -0,0 +1,9 @@
+---
+title: "Vibe Coding"
+description: "Experience AI-powered coding with real-time code execution, instant feedback, and interactive development where AI agents write, test, and iterate on code in live sandbox environments."
+icon: "wand-magic-sparkles"
+---
+
+# Vibe Coding
+
+Content coming soon.