From 99787ebb33990210df5456cafbc608c09a50cecd Mon Sep 17 00:00:00 2001 From: Danilo Woznica Date: Wed, 6 Nov 2024 13:28:09 +0000 Subject: [PATCH 01/12] Create sdk page --- packages/projects-docs/pages/_meta.json | 6 +- packages/projects-docs/pages/sdk/_meta.json | 9 ++ packages/projects-docs/pages/sdk/index.mdx | 95 +++++++++++++++++++++ 3 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 packages/projects-docs/pages/sdk/_meta.json create mode 100644 packages/projects-docs/pages/sdk/index.mdx diff --git a/packages/projects-docs/pages/_meta.json b/packages/projects-docs/pages/_meta.json index 741b5a23..95e35bd9 100644 --- a/packages/projects-docs/pages/_meta.json +++ b/packages/projects-docs/pages/_meta.json @@ -1,6 +1,10 @@ { + "sdk": { + "title": "SDK", + "type": "page" + }, "learn": { - "title": "Documentation", + "title": "Editor", "type": "page" }, "tutorial": { diff --git a/packages/projects-docs/pages/sdk/_meta.json b/packages/projects-docs/pages/sdk/_meta.json new file mode 100644 index 00000000..1d754f14 --- /dev/null +++ b/packages/projects-docs/pages/sdk/_meta.json @@ -0,0 +1,9 @@ +{ + "index": "Introduction", + "guides": "Getting Started", + "pricing": "Pricing", + "-- cloud-development": { + "type": "separator", + "title": "API Reference" + } +} \ No newline at end of file diff --git a/packages/projects-docs/pages/sdk/index.mdx b/packages/projects-docs/pages/sdk/index.mdx new file mode 100644 index 00000000..edc65791 --- /dev/null +++ b/packages/projects-docs/pages/sdk/index.mdx @@ -0,0 +1,95 @@ +--- +title: Overview +description: Learn how CodeSandbox works and the different types of projects you can create and develop. +--- + +import Hero from "../../../../shared-components/Hero.js" + +CodeSandbox SDK} +/> + +> The power of CodeSandbox in a library + +CodeSandbox SDK enables you to programmatically spin up development environments and run untrusted code. It provides a programmatic API to create and run sandboxes quickly and securely. + +Under the hood, the SDK uses the microVM infrastructure of CodeSandbox to spin up sandboxes. It supports: + +- Starting fresh VMs within 4 seconds +- Snapshotting/restoring VMs (checkpointing) at any point in time + - With snapshot restore times of less than 2 seconds +- Cloning VMs within 3 seconds +- Source control (git, GitHub, CodeSandbox SCM) +- Running any Dockerfile + +## Getting Started + +To get started, install the SDK: + +```bash +npm install @codesandbox/sdk +``` + +Then, create an API token by going to https://codesandbox.io/t/permissions, and clicking on the "Create API Token" button. You can then use this token to authenticate with the SDK: + +```javascript +import { CodeSandbox } from '@codesandbox/sdk'; + +// Create the client with your token +const sdk = new CodeSandbox(token); + +// This creates a new sandbox by forking our default template sandbox. +// You can also pass in other template ids, or create your own template to fork from. +const sandbox = await sdk.createSandbox(); + +// You can run JS code directly +await sandbox.shells.js.run("console.log(1+1)"); +// Or Python code (if it's installed in the template) +await sandbox.shells.python.run("print(1+1)"); + +// Or anything else +await sandbox.shells.run("echo 'Hello, world!'"); + +// We have a FS API to interact with the filesystem +await sandbox.fs.writeTextFile("./hello.txt", "world"); + +// And you can clone sandboxes! This does not only clone the filesystem, processes that are running in the original sandbox will also be cloned! +const sandbox2 = await sandbox.fork(); + +// Check that the file is still there +await sandbox2.fs.readTextFile("./hello.txt"); + +// You can also get the opened ports, with the URL to access those +console.log(sandbox2.ports.getOpenedPorts()); + +// Getting metrics... +const metrics = await sandbox2.getMetrics(); +console.log(`Memory: ${metrics.memory.usedKiB} KiB / ${metrics.memory.totalKiB} KiB`); +console.log(`CPU: ${(metrics.cpu.used / metrics.cpu.cores) * 100}%`); + +// Finally, you can hibernate a sandbox. This will snapshot the sandbox and stop it. Next time you start the sandbox, it will continue where it left off, as we created a memory snapshot. +await sandbox.hibernate(); +await sandbox2.hibernate(); + +// Open the sandbox again +const resumedSandbox = await sdk.openSandbox(sandbox.id); +``` + +## CodeSandbox Integration + +This SDK uses the API token from your workspace in CodeSandbox to authenticate and create sandboxes. Because of this, the sandboxes will be created inside your workspace, and the resources will be billed to your workspace. + +You could, for example, create a private template in your workspace that has all the dependencies you need (even running servers), and then use that template to fork sandboxes from. This way, you can control the environment that the sandboxes run in. + +## Example Use Cases + +These are some example use cases that you could use this library for: + +Code interpretation: Run code in a sandbox to interpret it. This way, you can run untrusted code without worrying about it affecting your system. + +Development environments: Create a sandbox for each developer, and run their code in the sandbox. This way, you can run multiple development environments in parallel without them interfering with each other. + +AI Agents: Create a sandbox for each AI agent, and run the agent in the sandbox. This way, you can run multiple agents in parallel without them interfering with each other. Using the forking mechanism, you can also A/B test different agents. + +CI/CD: Run tests inside a sandbox, and hibernate the sandbox when the tests are done. This way, you can quickly start the sandbox again when you need to run the tests again or evaluate the results. + From 8663f6265f5f58942d3e1c2f69f47f6784470119 Mon Sep 17 00:00:00 2001 From: Danilo Woznica Date: Thu, 7 Nov 2024 11:17:26 +0000 Subject: [PATCH 02/12] basic structure --- packages/projects-docs/pages/_meta.json | 14 +-- packages/projects-docs/pages/learn/_meta.json | 10 ++- packages/projects-docs/pages/sdk/_meta.json | 26 ++++-- packages/projects-docs/pages/sdk/faq.mdx | 0 .../pages/sdk/getting-started.mdx | 59 +++++++++++++ packages/projects-docs/pages/sdk/index.mdx | 85 +++---------------- .../projects-docs/pages/sdk/use-cases.mdx | 12 +++ 7 files changed, 123 insertions(+), 83 deletions(-) create mode 100644 packages/projects-docs/pages/sdk/faq.mdx create mode 100644 packages/projects-docs/pages/sdk/getting-started.mdx create mode 100644 packages/projects-docs/pages/sdk/use-cases.mdx diff --git a/packages/projects-docs/pages/_meta.json b/packages/projects-docs/pages/_meta.json index 95e35bd9..67aa6c90 100644 --- a/packages/projects-docs/pages/_meta.json +++ b/packages/projects-docs/pages/_meta.json @@ -1,18 +1,20 @@ { - "sdk": { - "title": "SDK", - "type": "page" - }, "learn": { "title": "Editor", "type": "page" }, + "sdk": { + "title": "SDK", + "type": "page" + }, "tutorial": { "title": "Tutorial", - "type": "page" + "type": "page", + "display": "hidden" }, "faq": { "title": "FAQ", - "type": "page" + "type": "page", + "display": "hidden" } } diff --git a/packages/projects-docs/pages/learn/_meta.json b/packages/projects-docs/pages/learn/_meta.json index ee675e1f..6264f582 100644 --- a/packages/projects-docs/pages/learn/_meta.json +++ b/packages/projects-docs/pages/learn/_meta.json @@ -29,5 +29,13 @@ "title": "More" }, "ci": "CodeSandbox CI", - "explore": "Discover Page" + "explore": "Discover Page", + "tutorials": { + "title": "Tutorials", + "href": "/tutorial/getting-started-with-dev-containers" + }, + "faq": { + "title": "FAQ", + "href": "/faq" + } } \ No newline at end of file diff --git a/packages/projects-docs/pages/sdk/_meta.json b/packages/projects-docs/pages/sdk/_meta.json index 1d754f14..fdf6198d 100644 --- a/packages/projects-docs/pages/sdk/_meta.json +++ b/packages/projects-docs/pages/sdk/_meta.json @@ -1,9 +1,25 @@ { - "index": "Introduction", - "guides": "Getting Started", - "pricing": "Pricing", - "-- cloud-development": { + "index": "Introduction", + "getting-started": "Getting Started", + "support": "Support", + + + "-- api-reference": { "type": "separator", "title": "API Reference" - } + }, + "sandboxes": "Sandboxes", + "filesystem": "File System", + "commands": "Commands", + "specs": "Specs", + "error-codes": "Error Codes", + + "-- resources": { + "type": "separator", + "title": "Resources" + }, + "pricing": "Pricing", + "use-cases": "Use Cases", + "examples": "Example Apps", + "faq": "FAQ" } \ No newline at end of file diff --git a/packages/projects-docs/pages/sdk/faq.mdx b/packages/projects-docs/pages/sdk/faq.mdx new file mode 100644 index 00000000..e69de29b diff --git a/packages/projects-docs/pages/sdk/getting-started.mdx b/packages/projects-docs/pages/sdk/getting-started.mdx new file mode 100644 index 00000000..7fcd44d5 --- /dev/null +++ b/packages/projects-docs/pages/sdk/getting-started.mdx @@ -0,0 +1,59 @@ +# Getting Started + +To get started, install the SDK: + +```bash +npm install @codesandbox/sdk +``` + +Then, create an API token by going to https://codesandbox.io/t/permissions, and clicking on the "Create API Token" button. You can then use this token to authenticate with the SDK: + +```javascript +import { CodeSandbox } from '@codesandbox/sdk'; + +// Create the client with your token +const sdk = new CodeSandbox(token); + +// This creates a new sandbox by forking our default template sandbox. +// You can also pass in other template ids, or create your own template to fork from. +const sandbox = await sdk.createSandbox(); + +// You can run JS code directly +await sandbox.shells.js.run("console.log(1+1)"); +// Or Python code (if it's installed in the template) +await sandbox.shells.python.run("print(1+1)"); + +// Or anything else +await sandbox.shells.run("echo 'Hello, world!'"); + +// We have a FS API to interact with the filesystem +await sandbox.fs.writeTextFile("./hello.txt", "world"); + +// And you can clone sandboxes! This does not only clone the filesystem, processes that are running in the original sandbox will also be cloned! +const sandbox2 = await sandbox.fork(); + +// Check that the file is still there +await sandbox2.fs.readTextFile("./hello.txt"); + +// You can also get the opened ports, with the URL to access those +console.log(sandbox2.ports.getOpenedPorts()); + +// Getting metrics... +const metrics = await sandbox2.getMetrics(); +console.log(`Memory: ${metrics.memory.usedKiB} KiB / ${metrics.memory.totalKiB} KiB`); +console.log(`CPU: ${(metrics.cpu.used / metrics.cpu.cores) * 100}%`); + +// Finally, you can hibernate a sandbox. This will snapshot the sandbox and stop it. Next time you start the sandbox, it will continue where it left off, as we created a memory snapshot. +await sandbox.hibernate(); +await sandbox2.hibernate(); + +// Open the sandbox again +const resumedSandbox = await sdk.openSandbox(sandbox.id); +``` + +## CodeSandbox Integration + +This SDK uses the API token from your workspace in CodeSandbox to authenticate and create sandboxes. Because of this, the sandboxes will be created inside your workspace, and the resources will be billed to your workspace. + +You could, for example, create a private template in your workspace that has all the dependencies you need (even running servers), and then use that template to fork sandboxes from. This way, you can control the environment that the sandboxes run in. + diff --git a/packages/projects-docs/pages/sdk/index.mdx b/packages/projects-docs/pages/sdk/index.mdx index edc65791..b9987cde 100644 --- a/packages/projects-docs/pages/sdk/index.mdx +++ b/packages/projects-docs/pages/sdk/index.mdx @@ -1,95 +1,38 @@ --- -title: Overview +title: CodeSandbox SDK description: Learn how CodeSandbox works and the different types of projects you can create and develop. --- -import Hero from "../../../../shared-components/Hero.js" +import Hero from "../../../../shared-components/Hero.js"; -CodeSandbox SDK} + -> The power of CodeSandbox in a library - -CodeSandbox SDK enables you to programmatically spin up development environments and run untrusted code. It provides a programmatic API to create and run sandboxes quickly and securely. +CodeSandbox SDK provides an API you can use to quickly create and run isolated development environments quickly and securely to run untrusted code. Under the hood, the SDK uses the microVM infrastructure of CodeSandbox to spin up sandboxes. It supports: - Starting fresh VMs within 4 seconds - Snapshotting/restoring VMs (checkpointing) at any point in time - - With snapshot restore times of less than 2 seconds + - With snapshot restore times of less than 2 seconds - Cloning VMs within 3 seconds - Source control (git, GitHub, CodeSandbox SCM) - Running any Dockerfile -## Getting Started - -To get started, install the SDK: - -```bash -npm install @codesandbox/sdk -``` - -Then, create an API token by going to https://codesandbox.io/t/permissions, and clicking on the "Create API Token" button. You can then use this token to authenticate with the SDK: +## In a nutshell -```javascript -import { CodeSandbox } from '@codesandbox/sdk'; +```js +import { CodeSandbox } from "@codesandbox/sdk"; -// Create the client with your token +// Create an isolated environment const sdk = new CodeSandbox(token); - -// This creates a new sandbox by forking our default template sandbox. -// You can also pass in other template ids, or create your own template to fork from. const sandbox = await sdk.createSandbox(); - -// You can run JS code directly -await sandbox.shells.js.run("console.log(1+1)"); -// Or Python code (if it's installed in the template) -await sandbox.shells.python.run("print(1+1)"); - -// Or anything else -await sandbox.shells.run("echo 'Hello, world!'"); - -// We have a FS API to interact with the filesystem -await sandbox.fs.writeTextFile("./hello.txt", "world"); - -// And you can clone sandboxes! This does not only clone the filesystem, processes that are running in the original sandbox will also be cloned! -const sandbox2 = await sandbox.fork(); - -// Check that the file is still there -await sandbox2.fs.readTextFile("./hello.txt"); - -// You can also get the opened ports, with the URL to access those -console.log(sandbox2.ports.getOpenedPorts()); -// Getting metrics... -const metrics = await sandbox2.getMetrics(); -console.log(`Memory: ${metrics.memory.usedKiB} KiB / ${metrics.memory.totalKiB} KiB`); -console.log(`CPU: ${(metrics.cpu.used / metrics.cpu.cores) * 100}%`); +// Run any server script +await sandbox.shells.python.run("print(1+1)"); -// Finally, you can hibernate a sandbox. This will snapshot the sandbox and stop it. Next time you start the sandbox, it will continue where it left off, as we created a memory snapshot. +// End the session (resume it whenever you want) await sandbox.hibernate(); -await sandbox2.hibernate(); - -// Open the sandbox again -const resumedSandbox = await sdk.openSandbox(sandbox.id); ``` - -## CodeSandbox Integration - -This SDK uses the API token from your workspace in CodeSandbox to authenticate and create sandboxes. Because of this, the sandboxes will be created inside your workspace, and the resources will be billed to your workspace. - -You could, for example, create a private template in your workspace that has all the dependencies you need (even running servers), and then use that template to fork sandboxes from. This way, you can control the environment that the sandboxes run in. - -## Example Use Cases - -These are some example use cases that you could use this library for: - -Code interpretation: Run code in a sandbox to interpret it. This way, you can run untrusted code without worrying about it affecting your system. - -Development environments: Create a sandbox for each developer, and run their code in the sandbox. This way, you can run multiple development environments in parallel without them interfering with each other. - -AI Agents: Create a sandbox for each AI agent, and run the agent in the sandbox. This way, you can run multiple agents in parallel without them interfering with each other. Using the forking mechanism, you can also A/B test different agents. - -CI/CD: Run tests inside a sandbox, and hibernate the sandbox when the tests are done. This way, you can quickly start the sandbox again when you need to run the tests again or evaluate the results. - diff --git a/packages/projects-docs/pages/sdk/use-cases.mdx b/packages/projects-docs/pages/sdk/use-cases.mdx new file mode 100644 index 00000000..67c7d1cb --- /dev/null +++ b/packages/projects-docs/pages/sdk/use-cases.mdx @@ -0,0 +1,12 @@ +# Use Cases + +These are some example use cases that you could use this library for: + +- **Code interpretation:** Run code in a sandbox to interpret it. This way, you can run untrusted code without worrying about it affecting your system. + +- **Development environments:** Create a sandbox for each developer, and run their code in the sandbox. This way, you can run multiple development environments in parallel without them interfering with each other. + +- **AI Agents:** Create a sandbox for each AI agent, and run the agent in the sandbox. This way, you can run multiple agents in parallel without them interfering with each other. Using the forking mechanism, you can also A/B test different agents. + +- **CI/CD:** Run tests inside a sandbox, and hibernate the sandbox when the tests are done. This way, you can quickly start the sandbox again when you need to run the tests again or evaluate the results. + From eb59293b5a14d3e80b032828ed5f3efd1bd81da2 Mon Sep 17 00:00:00 2001 From: Danilo Woznica Date: Wed, 13 Nov 2024 14:29:47 +0000 Subject: [PATCH 03/12] updates --- packages/projects-docs/pages/sdk/_meta.json | 6 +++- packages/projects-docs/pages/sdk/faq.mdx | 33 ++++++++++++++++++++ packages/projects-docs/pages/sdk/index.mdx | 16 +++++++--- packages/projects-docs/pages/sdk/pricing.mdx | 23 ++++++++++++++ 4 files changed, 72 insertions(+), 6 deletions(-) create mode 100644 packages/projects-docs/pages/sdk/pricing.mdx diff --git a/packages/projects-docs/pages/sdk/_meta.json b/packages/projects-docs/pages/sdk/_meta.json index fdf6198d..76d6c70c 100644 --- a/packages/projects-docs/pages/sdk/_meta.json +++ b/packages/projects-docs/pages/sdk/_meta.json @@ -1,8 +1,12 @@ { "index": "Introduction", "getting-started": "Getting Started", - "support": "Support", + "contact": { + "title": "Contact Us", + "href": "https://codesandbox.io/support#form", + "newWindow": true + }, "-- api-reference": { "type": "separator", diff --git a/packages/projects-docs/pages/sdk/faq.mdx b/packages/projects-docs/pages/sdk/faq.mdx index e69de29b..4e360be3 100644 --- a/packages/projects-docs/pages/sdk/faq.mdx +++ b/packages/projects-docs/pages/sdk/faq.mdx @@ -0,0 +1,33 @@ +--- +title: FAQs +--- + +import { Callout } from 'nextra-theme-docs' + +# FAQ + +## Do I need a CodeSandbox workspace to be able to use the SDK? + +Yes. You need a CodeSandbox API key to use CodeSandbox SDK, which you can get by creating a CodeSandbox account. + +## How can I revoke my API key? + +To revoke an API key, go to the "Permissions" tab of your [Workspace Settings](https://codesandbox.io/t/permissions) and click the respective token under "API Access". Then, click "Remove Token" from the bottom of that modal. + +## I have hit a rate limit - what should I do? + +Please [contact us](https://codesandbox.io/support#form) so we can lift the limit. + +## Can I change the specs of the VMs? + +Currently, we only allow changing the default specs for all VMs created with the SDK. You can change + +## How secure are these Devbox environments? + +Devbox environments are ... + +We are also SOC 2 Type II compliant. + +## Is it possible to self-host CodeSandbox SDK? + +No, for now we don't provide a self-host option. diff --git a/packages/projects-docs/pages/sdk/index.mdx b/packages/projects-docs/pages/sdk/index.mdx index b9987cde..6a0a0012 100644 --- a/packages/projects-docs/pages/sdk/index.mdx +++ b/packages/projects-docs/pages/sdk/index.mdx @@ -10,7 +10,7 @@ import Hero from "../../../../shared-components/Hero.js"; subtitle="Programmatically spin up development environments" /> -CodeSandbox SDK provides an API you can use to quickly create and run isolated development environments quickly and securely to run untrusted code. +CodeSandbox SDK (beta) provides an API you can use to quickly create and run isolated development environments quickly and securely to run untrusted code. Under the hood, the SDK uses the microVM infrastructure of CodeSandbox to spin up sandboxes. It supports: @@ -24,15 +24,21 @@ Under the hood, the SDK uses the microVM infrastructure of CodeSandbox to spin u ## In a nutshell ```js +// 1. Server import { CodeSandbox } from "@codesandbox/sdk"; // Create an isolated environment const sdk = new CodeSandbox(token); -const sandbox = await sdk.createSandbox(); +const sandboxInstance = await sdk.sandbox.fork("9qputt"); +``` + +```js +// 2. Browser +import { connectToSandbox } from "@codesandbox/sdk/browser"; + +// Safely connect sandbox instance in the browser +const sandbox = await connectToSandbox(sandboxInstance) // Run any server script await sandbox.shells.python.run("print(1+1)"); - -// End the session (resume it whenever you want) -await sandbox.hibernate(); ``` diff --git a/packages/projects-docs/pages/sdk/pricing.mdx b/packages/projects-docs/pages/sdk/pricing.mdx new file mode 100644 index 00000000..4417a24f --- /dev/null +++ b/packages/projects-docs/pages/sdk/pricing.mdx @@ -0,0 +1,23 @@ +--- +title: Pricing +--- + +import { Callout } from 'nextra-theme-docs' + +# Pricing + +CodeSandbox SDK is based on two main components: + +- VM credits (used to measure minutes of runtime of VMs created with the SDK) +- Rate limit tier (in case you require rate limits beyond our default) + +## VM credits pricing + +We price VM credits depending on the size of the VM being run. + +existing CodeSandbox pricing for VMs, with the addition + +Overview: + +- Pay-as-you-go for VM runtime (VM credits) +- Add-ons for higher rate limits From b9705bd66f7fc4d49542bf3a8ae6e2a6ba1ef76a Mon Sep 17 00:00:00 2001 From: Ives van Hoorne Date: Wed, 11 Dec 2024 00:24:43 +0000 Subject: [PATCH 04/12] lots of context --- packages/projects-docs/next-env.d.ts | 5 + packages/projects-docs/package.json | 4 +- .../pages/learn/devboxes/upload.mdx | 3 +- .../pages/learn/environment/vm.mdx | 2 +- packages/projects-docs/pages/sdk/_meta.json | 16 +- .../projects-docs/pages/sdk/environment.mdx | 22 ++ packages/projects-docs/pages/sdk/faq.mdx | 17 +- .../projects-docs/pages/sdk/filesystem.mdx | 88 +++++ .../pages/sdk/getting-started/_meta.json | 0 .../index.mdx} | 0 packages/projects-docs/pages/sdk/index.mdx | 69 ++-- .../pages/sdk/memory-snapshots.mdx | 53 +++ .../projects-docs/pages/sdk/persistence.mdx | 34 ++ packages/projects-docs/pages/sdk/ports.mdx | 130 +++++++ packages/projects-docs/pages/sdk/pricing.mdx | 56 ++- .../projects-docs/pages/sdk/sandboxes.mdx | 106 ++++++ packages/projects-docs/pages/sdk/shells.mdx | 115 +++++++ .../pages/sdk/snapshot-builder.mdx | 119 +++++++ packages/projects-docs/pages/sdk/specs.mdx | 57 ++++ packages/projects-docs/pages/sdk/tasks.mdx | 318 ++++++++++++++++++ .../pages/sdk/templates-component.tsx | 56 +++ .../projects-docs/pages/sdk/templates.mdx | 33 ++ .../projects-docs/pages/sdk/use-cases.mdx | 42 ++- .../projects-docs/public/snapshot-builder.mp4 | Bin 0 -> 19271046 bytes packages/projects-docs/styles.css | 89 +++++ packages/projects-docs/tsconfig.json | 28 ++ pnpm-lock.yaml | 19 +- shared-components/Video.js | 7 +- tsconfig.json | 5 + 29 files changed, 1441 insertions(+), 52 deletions(-) create mode 100644 packages/projects-docs/next-env.d.ts create mode 100644 packages/projects-docs/pages/sdk/environment.mdx create mode 100644 packages/projects-docs/pages/sdk/filesystem.mdx create mode 100644 packages/projects-docs/pages/sdk/getting-started/_meta.json rename packages/projects-docs/pages/sdk/{getting-started.mdx => getting-started/index.mdx} (100%) create mode 100644 packages/projects-docs/pages/sdk/memory-snapshots.mdx create mode 100644 packages/projects-docs/pages/sdk/persistence.mdx create mode 100644 packages/projects-docs/pages/sdk/ports.mdx create mode 100644 packages/projects-docs/pages/sdk/sandboxes.mdx create mode 100644 packages/projects-docs/pages/sdk/shells.mdx create mode 100644 packages/projects-docs/pages/sdk/snapshot-builder.mdx create mode 100644 packages/projects-docs/pages/sdk/specs.mdx create mode 100644 packages/projects-docs/pages/sdk/tasks.mdx create mode 100644 packages/projects-docs/pages/sdk/templates-component.tsx create mode 100644 packages/projects-docs/pages/sdk/templates.mdx create mode 100644 packages/projects-docs/public/snapshot-builder.mp4 create mode 100644 packages/projects-docs/tsconfig.json create mode 100644 tsconfig.json diff --git a/packages/projects-docs/next-env.d.ts b/packages/projects-docs/next-env.d.ts new file mode 100644 index 00000000..4f11a03d --- /dev/null +++ b/packages/projects-docs/next-env.d.ts @@ -0,0 +1,5 @@ +/// +/// + +// NOTE: This file should not be edited +// see https://nextjs.org/docs/basic-features/typescript for more information. diff --git a/packages/projects-docs/package.json b/packages/projects-docs/package.json index 2afb15d8..d965cf92 100644 --- a/packages/projects-docs/package.json +++ b/packages/projects-docs/package.json @@ -24,8 +24,10 @@ }, "devDependencies": { "autoprefixer": "^10.4.16", + "markdown-table": "^3.0.4", "postcss": "^8.4.31", - "tailwindcss": "^3.3.5" + "tailwindcss": "^3.3.5", + "typescript": "5.7.2" }, "prettier": { "embeddedLanguageFormatting": "off", diff --git a/packages/projects-docs/pages/learn/devboxes/upload.mdx b/packages/projects-docs/pages/learn/devboxes/upload.mdx index a7e6ccd5..878420e2 100644 --- a/packages/projects-docs/pages/learn/devboxes/upload.mdx +++ b/packages/projects-docs/pages/learn/devboxes/upload.mdx @@ -32,8 +32,7 @@ You can check your current Sandbox storage usage from your [Dashboard](https://c For Devboxes and repositories, the limits are: -- 20 GB total storage per Devbox or repository branch for workspaces on a Free plan. -- 50 GB total storage per Devbox or repository branch for workspaces on a Pro plan. +- 20 GB total storage per Devbox or repository branch for all workspaces. You can check your Devbox storage usage by clicking the CodeSandbox icon at the top left of the editor and then "Virtual machine". This will open a new DevTool displaying the current VM usage, including storage. diff --git a/packages/projects-docs/pages/learn/environment/vm.mdx b/packages/projects-docs/pages/learn/environment/vm.mdx index 706cec18..888a7400 100644 --- a/packages/projects-docs/pages/learn/environment/vm.mdx +++ b/packages/projects-docs/pages/learn/environment/vm.mdx @@ -22,7 +22,7 @@ VM resources consist of vCPU, RAM and storage. The vCPU and RAM specs are groupe | Subscription | Storage | | ------------ | ------- | | Free | 20 GB | -| Pro | 50 GB | +| Pro | 20 GB | If you require storage that goes beyond our Pro plan defaults, please select 'Pro Subscriptions' on our support form and [get in touch](https://codesandbox.io/support). Our team can adjust your limits to suit your project. diff --git a/packages/projects-docs/pages/sdk/_meta.json b/packages/projects-docs/pages/sdk/_meta.json index 76d6c70c..09fdff5a 100644 --- a/packages/projects-docs/pages/sdk/_meta.json +++ b/packages/projects-docs/pages/sdk/_meta.json @@ -7,23 +7,29 @@ "href": "https://codesandbox.io/support#form", "newWindow": true }, - + "-- api-reference": { "type": "separator", "title": "API Reference" }, "sandboxes": "Sandboxes", "filesystem": "File System", - "commands": "Commands", - "specs": "Specs", - "error-codes": "Error Codes", + "shells": "Shells", + "ports": "Ports & Previews", + "tasks": "Tasks & Setup", + "specs": "VM Specs", "-- resources": { "type": "separator", "title": "Resources" }, + "templates": "Templates", + "environment": "Environment", + "persistence": "Persistence", + "memory-snapshots": "Memory Snapshots", + "snapshot-builder": "Snapshot Builder", "pricing": "Pricing", "use-cases": "Use Cases", "examples": "Example Apps", "faq": "FAQ" -} \ No newline at end of file +} diff --git a/packages/projects-docs/pages/sdk/environment.mdx b/packages/projects-docs/pages/sdk/environment.mdx new file mode 100644 index 00000000..55718ced --- /dev/null +++ b/packages/projects-docs/pages/sdk/environment.mdx @@ -0,0 +1,22 @@ +--- +title: Environment +description: Learn how the CodeSandbox SDK's environment works. +--- + +import { Callout } from 'nextra-theme-docs' + +# Environment + +Sandboxes on CodeSandbox are backed by a [Firecracker](https://firecracker-microvm.github.io/) microVM, within the VM we run a rootless Docker container based on a [Dev Container](https://containers.dev/) configuration (specified in the `.devcontainer/devcontainer.json` file). + +## Booting a Sandbox + +Whenever we boot a sandbox from scratch, we'll: + +1. Start the Firecracker VM +2. Create a default user (called `pitcher-host`) +3. (optional) Build the Docker image specified in the `.devcontainer/devcontainer.json` file +4. Start the Docker container +5. Mount the `/project/sandbox` directory as a volume inside the Docker container + +We run an agent inside the VM that the SDK connects to. Via an RPC protocol you can then interact with the sandbox. diff --git a/packages/projects-docs/pages/sdk/faq.mdx b/packages/projects-docs/pages/sdk/faq.mdx index 4e360be3..98a2e1e8 100644 --- a/packages/projects-docs/pages/sdk/faq.mdx +++ b/packages/projects-docs/pages/sdk/faq.mdx @@ -1,5 +1,6 @@ --- title: FAQs +description: Find answers to common questions about the CodeSandbox SDK. --- import { Callout } from 'nextra-theme-docs' @@ -8,7 +9,7 @@ import { Callout } from 'nextra-theme-docs' ## Do I need a CodeSandbox workspace to be able to use the SDK? -Yes. You need a CodeSandbox API key to use CodeSandbox SDK, which you can get by creating a CodeSandbox account. +Yes. You need a CodeSandbox API key to use CodeSandbox SDK, which you can get by [creating a CodeSandbox account](https://codesandbox.io/signin). ## How can I revoke my API key? @@ -16,7 +17,7 @@ To revoke an API key, go to the "Permissions" tab of your [Workspace Settings](h ## I have hit a rate limit - what should I do? -Please [contact us](https://codesandbox.io/support#form) so we can lift the limit. +Please subscribe to a CodeSandbox plan that includes the most suitable rate limit for you. In case you're on our Builder plan already, please [contact us](https://webforms.pipedrive.com/f/72gS7iXoP8qjL8Ku9HZQcN5UKpUpZkgKRCjhbqREjCOYyBgzrCKCr7Mys5AyczOHBN) to discuss an Enterprise plan. ## Can I change the specs of the VMs? @@ -31,3 +32,15 @@ We are also SOC 2 Type II compliant. ## Is it possible to self-host CodeSandbox SDK? No, for now we don't provide a self-host option. + +## Are there any SDK rate limits? + +Yes. The SDK has rate limits on concurrent VMs, number of requests per hour, and number of sandboxes created per hour. These limits vary depending on the CodeSandbox plan, as explained on our [Pricing page](https://codesandbox.io/pricing). + +## Can I use the same CodeSandbox plan for SDK and non-SDK usage? + +Yes. Your CodeSandbox plan will allow you to use both, so you can leverage the SDK for programmatic sandbox creation, while still allowing your team to use CodeSandbox for their development. + +## Does the CodeSandbox SDK use CodeSandbox Sandboxes or Devboxes? + +While the SDK code only mentions "sandbox", the actual environments that it uses are officially called "Devboxes" (which use VMs). So, if you need more details about these VMs, please always refer to "[Devbox](/learn/devboxes/overview)" section of the CodeSandbox documentation and pricing. diff --git a/packages/projects-docs/pages/sdk/filesystem.mdx b/packages/projects-docs/pages/sdk/filesystem.mdx new file mode 100644 index 00000000..cd004e2d --- /dev/null +++ b/packages/projects-docs/pages/sdk/filesystem.mdx @@ -0,0 +1,88 @@ +--- +title: File System +description: Learn how the CodeSandbox SDK's file system works. +--- + +# File System + +Every sandbox has a persistent file system under `/project/sandbox`. By default, the working directory is `/project/sandbox`. All files saved in `/project/sandbox` have `git` source control and will be persisted between reboots. Whenever we hibernate or shutdown a sandbox, we'll create a commit to track the filesystem of the sandbox. + +Refer to the [Environment](/sdk/environment) section for more information about how we store files and other resources. + +## API + +The API of the filesystem is similar to the Node.js fs module. You can find the API under `sandbox.fs`. All filesystem +operations are relative to the workspace directory of the sandbox (which is `/project/sandbox` by default). + +### Writing & Reading Files + +You can read & write files using an api that's similer to the Node.js fs module: + +```ts +const sandbox = await sdk.sandbox.create(); + +// Writing text files +await sandbox.fs.writeTextFile("./hello.txt", "Hello, world!"); + +// Reading text files +const content = await sandbox.fs.readTextFile("./hello.txt"); +console.log(content); + +// Writing binary files +await sandbox.fs.writeFile("./hello.bin", new Uint8Array([1, 2, 3])); + +// Reading binary files +const content = await sandbox.fs.readFile("./hello.bin"); +console.log(content); +``` + +### Uploading & Downloading Files + +Uploading and downloading files can be done using the same methods as writing and reading files. + +```ts +import fs from "node:fs"; + +const sandbox = await sdk.sandbox.create(); + +const myBinaryFile = fs.readFileSync("./my-binary-file"); +await sandbox.fs.writeFile("./my-binary-file", myBinaryFile); + +const content = await sandbox.fs.readFile("./my-binary-file"); +fs.writeFileSync("./my-binary-file", content); +``` + +### Listing Files & Directories + +You can list files & directories in a directory using the `readdir` method. + +```ts +const filesOrDirs = await sandbox.fs.readdir("./"); + +console.log(filesOrDirs); +``` + +### Copying, Renaming & Deleting Files + +You can copy, rename & delete files using the `copy`, `rename` & `remove` methods. + +```ts +await sandbox.fs.copy("./hello.txt", "./hello-copy.txt"); +await sandbox.fs.rename("./hello-copy.txt", "./hello-renamed.txt"); +await sandbox.fs.remove("./hello-renamed.txt"); +``` + +### Watching Files + +You can watch files for file changes, additions and deletions using the `watch` method. + +```ts +const watcher = await sandbox.fs.watch("./", { recursive: true, excludes: [".git"] }); + +watcher.onEvent((event) => { + console.log(event); +}); + +// When you're done, you can stop the watcher +watcher.dispose(); +``` diff --git a/packages/projects-docs/pages/sdk/getting-started/_meta.json b/packages/projects-docs/pages/sdk/getting-started/_meta.json new file mode 100644 index 00000000..e69de29b diff --git a/packages/projects-docs/pages/sdk/getting-started.mdx b/packages/projects-docs/pages/sdk/getting-started/index.mdx similarity index 100% rename from packages/projects-docs/pages/sdk/getting-started.mdx rename to packages/projects-docs/pages/sdk/getting-started/index.mdx diff --git a/packages/projects-docs/pages/sdk/index.mdx b/packages/projects-docs/pages/sdk/index.mdx index 6a0a0012..fcf52d3a 100644 --- a/packages/projects-docs/pages/sdk/index.mdx +++ b/packages/projects-docs/pages/sdk/index.mdx @@ -7,38 +7,67 @@ import Hero from "../../../../shared-components/Hero.js"; -CodeSandbox SDK (beta) provides an API you can use to quickly create and run isolated development environments quickly and securely to run untrusted code. +CodeSandbox SDK (beta) enables you to quickly create and run isolated sandboxes securely. +The SDK can be used to run concurrent VMs to support multiple usecases such as AI agents, code interpretation and [more](./usecases.mdx) + +## How it works + +The API spins up a sandbox with a fresh VM in under 4 seconds. Inside this VM, you can run any code, install any dependencies and even run a server. + +The sandboxes run on the same infrastructure as CodeSandbox, which means you can clone, snapshot and restore sandboxes at any point in time (checkpointing). Under the hood, the SDK uses the microVM infrastructure of CodeSandbox to spin up sandboxes. It supports: -- Starting fresh VMs within 4 seconds -- Snapshotting/restoring VMs (checkpointing) at any point in time - - With snapshot restore times of less than 2 seconds -- Cloning VMs within 3 seconds -- Source control (git, GitHub, CodeSandbox SCM) -- Running any Dockerfile +1. Memory snapshot/restore (checkpointing) at any point in time +2. Resume/clone VMs from a snapshot in 3 seconds +3. VM FS persistence (with `git` version control) +4. Environment customization using Docker & Docker Compose (Dev Containers) -## In a nutshell +## Quickstart -```js -// 1. Server -import { CodeSandbox } from "@codesandbox/sdk"; +Install the SDK: -// Create an isolated environment -const sdk = new CodeSandbox(token); -const sandboxInstance = await sdk.sandbox.fork("9qputt"); +```bash +npm install @codesandbox/sdk ``` +Create an API key at [https://codesandbox.io/t/api](https://codesandbox.io/t/api), and enable all scopes. + +Now you can create a sandbox and run a server: + ```js -// 2. Browser -import { connectToSandbox } from "@codesandbox/sdk/browser"; +import { CodeSandbox } from "@codesandbox/sdk"; -// Safely connect sandbox instance in the browser -const sandbox = await connectToSandbox(sandboxInstance) +const sdk = new CodeSandbox(process.env.CSB_API_KEY!); +const sandbox = await sdk.sandbox.create(); -// Run any server script await sandbox.shells.python.run("print(1+1)"); +await sandbox.shells.run('echo "Hello World"'); + +// We can also start shells in the background by not awaiting them +const shellInfo = sandbox.shells.run("npx -y serve ."); + +// Wait for port to open +const portInfo = await sandbox.ports.waitForPort(3000); +console.log(portInfo.toPreviewUrl()); + +// And, we can clone(!) the sandbox! This takes 1-3s. +const sandbox2 = await sandbox.fork(); + +// Sandbox 2 will have the same processes running as sandbox 1 +const portInfo2 = await sandbox2.ports.waitForPort(3000); +console.log(portInfo2.toPreviewUrl()); + +// Finally, we can hibernate the sandbox. This will snapshot the sandbox and stop it. +// Next time you start the sandbox, it will continue where it left off, as we created a memory snapshot. +// The sandboxes will also automatically resume if a network request comes in for the +// servers they have started. +await sandbox.hibernate(); +await sandbox2.hibernate(); + +// Open the sandbox again +const resumedSandbox = await sdk.openSandbox(sandbox.id); ``` diff --git a/packages/projects-docs/pages/sdk/memory-snapshots.mdx b/packages/projects-docs/pages/sdk/memory-snapshots.mdx new file mode 100644 index 00000000..66addb84 --- /dev/null +++ b/packages/projects-docs/pages/sdk/memory-snapshots.mdx @@ -0,0 +1,53 @@ +--- +title: Memory Snapshots +description: Learn how memory snapshots work in the CodeSandbox SDK. +--- + +# Memory Snapshots + +When you hibernate a sandbox, we keep a memory snapshot of the underlying Firecracker VM. When you start that sandbox, or if any network request is made to the sandbox, we'll restore the memory snapshot and continue from where you left off. + +## Manually Creating a Memory Snapshot + +You can manually create a memory snapshot by calling `sandbox.hibernate()`: + +```ts +import { CodeSandbox } from '@codesandbox/sdk' +const sdk = new CodeSandbox(); + +const sandbox = await sdk.sandbox.create(); + +// Do work + +await sandbox.hibernate(); +``` + +Creating a memory snapshot can take between 3-10 seconds. Resuming from a memory snapshot takes between 0.5-2 seconds. + +## Cloning a Sandbox + +Because we can snapshot a sandbox, we can also clone it! For example, you can clone a sandbox to create a new sandbox running the same server. + +```ts +import { CodeSandbox } from '@codesandbox/sdk' +const sdk = new CodeSandbox(); + +const sandbox = await sdk.sandbox.create(); + +// Run anything on the sandbox +await sandbox.shells.run('echo test > test.txt'); + +const sandbox2 = await sandbox.fork(); + +// Now we have two sandboxes that have the same fs & memory state! +``` + +You could use this to add support for checkpoint/restore functionality, or A/B test different agent iterations. At CodeSandbox we use this to enable forking of sandboxes. Someone can share a template, and someone else can click "Fork" to create a new sandbox based on the same state. + +## Learn More + +We have written a couple blog posts about how memory snapshots work under the hood: + +- [How we clone a running VM in 2 seconds](https://codesandbox.io/blog/how-we-clone-a-running-vm-in-2-seconds) +- [Cloning microVMs by sharing memory through userfaultfd](https://codesandbox.io/blog/cloning-microvms-using-userfaultfd) +- [How we scale our microVM infrastructure using low-latency memory decompression](https://codesandbox.io/blog/how-we-scale-our-microvm-infrastructure-using-low-latency-memory-decompression) diff --git a/packages/projects-docs/pages/sdk/persistence.mdx b/packages/projects-docs/pages/sdk/persistence.mdx new file mode 100644 index 00000000..ae52bb96 --- /dev/null +++ b/packages/projects-docs/pages/sdk/persistence.mdx @@ -0,0 +1,34 @@ +--- +title: Persistence +description: Learn how the persistence of sandboxes works. +--- + +import { Callout } from 'nextra-theme-docs' + +# Persistence + +Sandboxes have three states of persistence: + +- **Memory**: the sandbox has a memory snapshot and will be restored from memory when started. This takes 1-2 seconds. +- **Disk**: the sandbox has a disk snapshot, but needs to boot from scratch. This takes 5-20 seconds. +- **Archived**: the sandbox has no disk, and will be recreated from our archive storage. This takes 20-60 seconds. + +Generally, a sandbox will have a memory snapshot for 7 days, a disk snapshot for 2 weeks, and an archive for undetermined time (so far in the last 4 years, we've never deleted an archive). + +## Disk + +Sandboxes have two layers of disk persistence: + +- `/persisted`: contains our archive of the sandbox. If you start a sandbox after a year of inactivity, the `/persisted` directory will still be there. Because of this, it's smaller than the `/project/sandbox` directory. + + +We keep a `.git` directory in `/persisted` to track the filesystem of the sandbox, which we regularly commit to. + + +- `/project/sandbox`: this is the working directory of the sandbox. All files saved in this directory will be persisted between reboots. If the sandbox is not started for more than a week (or longer, depending on plan and disk pressure), we'll commit all files of `/project/sandbox` to `/persisted` and delete the disk. If the persisting of files fails, we won't delete the disk to ensure the user's data is not lost. + +## Memory + +Whenever a sandbox is hibernated, we keep a memory snapshot of the underlying Firecracker VM. Then, when you start that sandbox, or if any network request is made to the sandbox, we'll restore the memory snapshot and continue from where you left off (this takes 0.5-2 seconds). + +Memory snapshots are kept for a week (can be longer depending on plan, and disk pressure), after which they'll be deleted. If the sandbox was used in the meantime (either the sandbox was resumed, or the sandbox was forked), the memory snapshot will be kept around and the timer will reset. diff --git a/packages/projects-docs/pages/sdk/ports.mdx b/packages/projects-docs/pages/sdk/ports.mdx new file mode 100644 index 00000000..bddc3afd --- /dev/null +++ b/packages/projects-docs/pages/sdk/ports.mdx @@ -0,0 +1,130 @@ +--- +title: Ports +description: Learn how you can interact with ports in your sandbox. +--- + +import { Callout } from 'nextra-theme-docs' + +# Ports + +The Ports API allows you to monitor and interact with HTTP ports in your sandbox. This is particularly useful when working with development servers or any other services that listen on specific ports. + +Whenever a port is opened within a sandbox, we'll automatically expose it under `https://-.csb.app`. + + +If the sandbox is private, we'll ask the user to sign in to open the preview. We're currently working on an API to allow creating signed URLs for private sandboxes, or selecting which ports are exposed and which are closed. + + +Also, we'll automatically resume a sandbox whenever a port is accessed while the sandbox is hibernated. + +## API + +The Ports API is available under `sandbox.ports`. It provides methods for monitoring port activity and getting preview URLs for web services. + +### Monitoring Ports + +You can listen for ports being opened and closed in your sandbox: + +```ts +const sandbox = await sdk.sandbox.create(); + +// Listen for ports being opened +const listener1 = sandbox.ports.onDidPortOpen((portInfo) => { + console.log(`Port ${portInfo.port} opened`); + console.log(`Preview URL: ${portInfo.getPreviewUrl()}`); +}); + +// Listen for ports being closed +const listener2 = sandbox.ports.onDidPortClose((port) => { + console.log(`Port ${port} closed`); +}); + +// Remove listeners when done +listener1.dispose(); +listener2.dispose(); +``` + +### Getting Port Information + +You can get information about currently opened ports: + +```ts +const sandbox = await sdk.sandbox.create(); + +// Get all opened ports +const openPorts = sandbox.ports.getOpenedPorts(); +for (const port of openPorts) { + console.log(`Port ${port.port} is open at ${port.hostname}`); +} + +// Get preview URL for a specific port +const previewUrl = sandbox.ports.getPreviewUrl(3000); +if (previewUrl) { + console.log(`Preview available at: ${previewUrl}`); +} +``` + +### Waiting for Ports + +When starting services, you often need to wait for a port to become available: + +```ts +const sandbox = await sdk.sandbox.create(); + +// Start a development server +sandbox.shells.run("npm run dev"); + +// Wait for the dev server port to open +const portInfo = await sandbox.ports.waitForPort(3000); +console.log(`Dev server is ready at: ${portInfo.getPreviewUrl()}`); +``` + +## Examples + +### Starting a Web Server + +Here's a complete example of starting a web server and getting its preview URL: + +```ts +const sandbox = await sdk.sandbox.create(); + +// Start the server +sandbox.shells.run("npx serve -y ."); + +// Wait for the server to be ready +const portInfo = await sandbox.ports.waitForPort(3000); + +// Get the preview URL with custom protocol +const httpUrl = portInfo.getPreviewUrl("http://"); +const httpsUrl = portInfo.getPreviewUrl(); // defaults to https:// + +console.log(`Server is running at: +- HTTP: ${httpUrl} +- HTTPS: ${httpsUrl}`); +``` + +### Monitoring Multiple Ports + +When working with multiple services, you might want to monitor several ports: + +```ts +const sandbox = await sdk.sandbox.create(); + +// Start monitoring before launching services +sandbox.ports.onDidPortOpen((portInfo) => { + switch (portInfo.port) { + case 3000: + console.log("Frontend server ready"); + break; + case 3001: + console.log("API server ready"); + break; + case 5432: + console.log("Database ready"); + break; + } +}); + +// Start your services +sandbox.shells.run("npm run start:all"); +``` diff --git a/packages/projects-docs/pages/sdk/pricing.mdx b/packages/projects-docs/pages/sdk/pricing.mdx index 4417a24f..1e388f1f 100644 --- a/packages/projects-docs/pages/sdk/pricing.mdx +++ b/packages/projects-docs/pages/sdk/pricing.mdx @@ -1,23 +1,61 @@ --- title: Pricing +description: Learn how CodeSandbox SDK is priced, find your ideal plan, and estimate your bill. --- import { Callout } from 'nextra-theme-docs' # Pricing -CodeSandbox SDK is based on two main components: +CodeSandbox SDK is priced according to the [CodeSandbox plans](https://codesandbox.io/pricing). The SDK follows two main pricing components: -- VM credits (used to measure minutes of runtime of VMs created with the SDK) -- Rate limit tier (in case you require rate limits beyond our default) +- **VM credits**: Credits serve as the unit of measurement for VM runtime. One credit equates to a specific amount of resources used per hour, depending on the specs of the VM you are using. VM credits follow a pay-as-you-go approach and are priced at $0.018 per credit. Learn more about credits [here](/learn/credit-usage/credits). -## VM credits pricing +- **VM concurrency**: This defines the maximum number of VMs you can run simultaneously with the SDK. As explored below, each CodeSandbox plan has a different VM concurrency limit. -We price VM credits depending on the size of the VM being run. +We use minutes as the smallest unit of measurement for VM credits. E.g.: if a VM runs for 3 minutes and 25 seconds, we bill the equivalent of 4 minutes of VM runtime. -existing CodeSandbox pricing for VMs, with the addition +## VM credit prices by VM size -Overview: +Below is a summary of how many VM credits are used per hour of runtime in each of our available VM sizes. Note that, by default, we recommend using the Pico VM size, as it should provide enough resources for most workflows that require basic code interpretation. -- Pay-as-you-go for VM runtime (VM credits) -- Add-ons for higher rate limits +| VM size | Credits / hour | Cost / hour | CPU | RAM | +| ------- | -------------- | ----------- | -------- | ------ | +| Pico | 7 credits | $0.126 | 2 cores | 1 GB | +| Nano | 10 credits | $0.18 | 2 cores | 4 GB | +| Micro | 20 credits | $0.36 | 4 cores | 8 GB | +| Small | 40 credits | $0.72 | 8 cores | 16 GB | +| Medium | 80 credits | $1.44 | 16 cores | 32 GB | +| Large | 160 credits | $2.88 | 32 cores | 64 GB | +| XLarge | 320 credits | $5.76 | 64 cores | 128 GB | + +## Concurrent VMs + +To pick the most suitable plan for your use case, consider how many concurrent VMs you require and pick the corresponding plan: + +- Free plan: 5 concurrent VMs +- Pro plan: 20 concurrent VMs +- Builder plan: 100 concurrent VMs +- Enterprise plan: custom concurrent VMs + +In case you expect a a high volume of VM runtime, our Enterprise plan also provides special discounts (up to 50% off) on VM credits. + +## Estimating your bill + +To estimate your bill, you must consider: + +- The base price of your CodeSandbox plan. +- The number of included VM credits on that plan. +- How many VM credits you expect to require. + +As an example, let's say you are planning to run 80 concurrent VMs on average, each running 3 hours per day, every day, on the Pico VM size. Here's the breakdown: + +- You will need a Builder plan (which allows up to 100 concurrent VMs). +- You will use a total of 50,400 VM credits per month (80 VMs x 3 hours/day x 30 days x 7 credits/hour). +- Your Builder plan includes 1100 free VM credits each month, so you will purchase 49,300 VM credits (50,400 - 1100). + +Based on this, your expected bill for that month is: + +- Base price of Builder plan: $170 +- Total price of VM credits: $887.40 (49,300 VM credits x $0.018/credit) +- Total bill: $1057.40 diff --git a/packages/projects-docs/pages/sdk/sandboxes.mdx b/packages/projects-docs/pages/sdk/sandboxes.mdx new file mode 100644 index 00000000..c43b4181 --- /dev/null +++ b/packages/projects-docs/pages/sdk/sandboxes.mdx @@ -0,0 +1,106 @@ +--- +title: Sandboxes +description: Learn how to create sandboxes with the CodeSandbox SDK. +--- + +import { Callout } from 'nextra-theme-docs' + +# Sandboxes + +Sandboxes are the main building block of the CodeSandbox SDK. They represent a single project that you can run, fork, and modify. They are backed by a Firecracker VM. Sandboxes are completely isolated, and persisted, so you can securely run untrusted code in them. + +## Creating a Sandbox + +You can create a sandbox by calling `sandbox.create()`: + +```ts +import { CodeSandbox } from '@codesandbox/sdk' +const sdk = new CodeSandbox(); + +const sandbox = await sdk.sandbox.create(); +``` + +If no argument is provided to `sandbox.create()`, we'll create a sandbox based on our [Universal](https://codesandbox.io/p/devbox/universal-pcz35m) template on CodeSandbox. You can also pass in a template id, either from [our collection of templates](/sdk/templates) or by creating your own snapshot using our [Snapshot Builder](/sdk/snapshot-builder). + +## Opening an Existing Sandbox + +You can also open an existing sandbox by calling `sandbox.open()`: + +```ts +const sandbox = await sdk.sandbox.open('sandbox-id'); +``` + +This will start the sandbox and connect to it. + +## Opening a Sandbox from the Browser + +It's possible to connect to a sandbox directly from the browser without sharing your API key with the frontend. You can do this by generating a single-use token from the server: + +```ts +import { CodeSandbox } from '@codesandbox/sdk' +const sdk = new CodeSandbox(); + +// This is from the server +const startData = await sdk.sandbox.start('sandbox-id'); +``` + +From the browser, you can use this start data to connect to the sandbox: + +```ts +import { connectToSandbox } from '@codesandbox/sdk/browser' + +// Fetch the start data from the server +const startData = await fetch('/api/start-sandbox').then(res => res.json()); + +const sandbox = await connectToSandbox(startData); + +// Now you can do whatever you normally do using the SDK +await sandbox.fs.writeFile('./index.html', '

Hello World

'); +sandbox.shells.run('npx -y serve .') +console.log((await sandbox.ports.waitForPort(3000)).getPreviewUrl()) +``` + + +Some APIs are not available when connecting from the browser. For example, you can't hibernate, shutdown or fork a sandbox. + + +## Hibernation & Hibernation Timeout + +When you're done with a sandbox, you can hibernate it. This will save the memory state of the sandbox, so it will resume from the same state when you start it again. + +```ts +await sandbox.hibernate(); +``` + +When starting a sandbox, you can also set a hibernation timeout between 1 minute and 24 hours. By default this timeout is 5 minutes for free users, and 30 minutes for paid users. + +```ts +import { CodeSandbox } from '@codesandbox/sdk' +const sdk = new CodeSandbox(); + +const sandbox = await sdk.sandbox.create({ + hibernationTimeoutSeconds: 60 * 60 * 1 // 1 hour +}); +``` + +When you set a hibernation timeout, the sandbox will hibernate after the specified period of inactivity (no calls from the SDK). While the SDK remains connected, we recommend either explicitly hibernating the sandbox or disconnecting from it when you're done using it. Since resuming only takes a few seconds, you can be aggressive with hibernation to conserve resources. + +## Disconnecting from a Sandbox + +Alternatively, you can disconnect from the sandbox. In this case, it will automatically hibernate after the timeout: + +```ts +await sandbox.disconnect(); +``` + +You can do this if you want a user to still interact with the sandbox, but don't need to keep the SDK connected. + +## Shutdown + +Finally, you can also shutdown a sandbox. This will shut down the sandbox without creating a memory snapshot. Next time the sandbox is started, it will boot from a clean state (but your files in `/project/sandbox` will be preserved). + +```ts +await sandbox.shutdown(); +``` + +Generally you should shutdown a sandbox if you want to start from a clean state. diff --git a/packages/projects-docs/pages/sdk/shells.mdx b/packages/projects-docs/pages/sdk/shells.mdx new file mode 100644 index 00000000..be1d2caf --- /dev/null +++ b/packages/projects-docs/pages/sdk/shells.mdx @@ -0,0 +1,115 @@ +--- +title: Shells +description: Learn how the CodeSandbox SDK's shells work. +--- + +# Shells + +The Shell API allows you to create, manage and interact with shell processes in your sandbox. You can create interactive shells, run commands, and execute code in different programming languages. + +## API + +The Shell API is available under `sandbox.shells`. It provides methods for creating shells, running commands, and managing shell instances. + +### Creating Interactive Shells + +You can create an interactive shell that allows you to send commands and receive output: + +```ts +const sandbox = await sdk.sandbox.create(); + +// Create a new shell (defaults to bash) +const shell = await sandbox.shells.create(); + +// Listen to shell output +shell.onShellOut((output) => { + console.log(output); +}); + +// Send commands to the shell +await shell.write("echo 'Hello, world!'"); + +// Kill the shell when done +await shell.kill(); +``` + +### Running Commands + +For simple command execution, you can use the `run` method which returns a promise with the command's output: + +```ts +const sandbox = await sdk.sandbox.create(); + +// Run a single command +const command = sandbox.shells.run("npm install"); + +// Listen to real-time output +command.onOutput((output) => { + console.log(output); +}); + +// Optionally cancel the command if it's not finished +if (Math.random() > 0.5) { + command.kill(); +} + +// Wait for completion and get results +const result = await command; +console.log(result.output, result.exitCode); +``` + +### Language Interpreters + +The Shell API includes built-in support for running code in different programming languages: + +```ts +const sandbox = await sdk.sandbox.create(); + +// Run JavaScript code +const jsResult = await sandbox.shells.js.run(` + console.log("Hello from Node.js!"); +`); + +// Run Python code +const pythonResult = await sandbox.shells.python.run(` + print("Hello from Python!") +`); +``` + +These interpreters are built on top of the `run` method, so you can use the same options and event listeners. Currently, we only support `python` and `js` interpreters, but we're working on adding more. In the meantime you can use the `run` method to run any command. + +### Managing Shell Instances + +You can list and reconnect to existing shells: + +```ts +const sandbox = await sdk.sandbox.create(); + +// Get all shells +const shells = await sandbox.shells.getShells(); + +// Reconnect to an existing shell +const shell = await sandbox.shells.open(shellId); + +// Check shell status and info +console.log(shell.status); // "RUNNING" | "FINISHED" | "ERROR" | "KILLED" | "RESTARTING" +console.log(shell.exitCode); +console.log(shell.getOutput()); +``` + +## Examples + +### Starting a server and waiting for the port to open + +```ts +const sandbox = await sdk.sandbox.create(); + +const shell = await sandbox.shells.create(); + +// Run in background by not awaiting the command +shell.run("npx serve -y ."); + +const portInfo = await shell.waitForPort(3000); + +console.log(portInfo.getPreviewUrl()); +``` diff --git a/packages/projects-docs/pages/sdk/snapshot-builder.mdx b/packages/projects-docs/pages/sdk/snapshot-builder.mdx new file mode 100644 index 00000000..e9457ea4 --- /dev/null +++ b/packages/projects-docs/pages/sdk/snapshot-builder.mdx @@ -0,0 +1,119 @@ +--- +title: Snapshot Builder +description: Learn how to create your own templates with the CodeSandbox SDK. +--- + +import Video from '../../../../shared-components/Video' + +# Snapshot Builder + +If you’re using CodeSandbox SDK, there’s a big chance that you want to customize the base environment of your sandboxes. You might want to preload a custom Docker image, or prestart a server that should be available as soon as you create a sandbox. + +You can use our CLI to create a memory snapshot that has all this data preloaded. This CLI will build a sandbox based on a folder, load the docker image, start the servers and finally create a memory snapshot that can be used when creating new sandboxes. + +New sandboxes can be created from this memory snapshot, which means that new sandboxes will “hit the ground running” with the servers running during snapshot creation. Creating a sandbox from a memory snapshot takes 1-3 seconds. + +