• Advanced Usage
  • Nodebox

Nodebox

Run Node in any browser.

Nodebox is a runtime for executing Node.js code in the browser. Sandpack 2.0 uses Nodebox to run server-side examples directly in the browser. For example, you can run a Vite template such as React and Vue directly on your website.

You can use Nodebox as an NPM package or together with Sandpack 2.0.

Server-side support

Nodebox with out-of-the-box support for Next.js, Vite and Astro, but we’re growing to support just about any server-side framework you can imagine.

However, bear in mind it can’t run napi or any other low-level C++/Rust package you can use in Node.js—only WebAssembly and JavaScript modules. Postgres, MongoDB and MySQL are also currently not supported because of the lack of raw socket support in browsers.

Difference with WebContainers

Web Containers use modern browser technologies like SharedArrayBuffer, which makes it impossible to run in Safari and requires the user to set additional Cross-Origin-Isolation headers on the server to run any code.

Nodebox however, is implemented without modern browser technologies, to make it run in any browser (like iOS and Safari) with minimal setup.

For further details, check the Nodebox FAQ.

Install Nodebox

npm i @codesandbox/nodebox

Configure and connect

To set up Nodebox, first add an <iframe> to your html. Using the reference to this iframe nodebox can register itself and execute code inside the iframe without any security risks. To render previews you require a secondary <iframe>. In this example we have 2 iframes: #nodebox-runtime-iframe for running the node code and #nodebox-runtime-preview for rendering the output of the server.

In your Script element input the following:

import { Nodebox } from '@codesandbox/nodebox';
 
const emulator = new Nodebox({
  iframe: document.getElementById('nodebox-runtime-iframe'),
});
 
await emulator.connect();

This will Initialize a new Nodebox instance and load the nodebox runtime in the #nodebox-runtime-iframe iframe, ready to execute your code.

Initialize file system

Next, populate the emulator's file system with your project files.

In this example, we will be running a simple HTTP server written in the main.js module.

await emulator.fs.init({
  'package.json': JSON.stringify({
    name: 'my-app',
  }),
  'main.js': `
import http from 'http'
 
const server = http.createServer((req, res) => {
  res.writeHead(200, {
    'Content-Type': 'text/plain'
  })
 res.end('Hello from Nodebox')
})
 
server.listen(3000, () => {
  console.log('Server is ready!')
})
  `,
});

You can reference built-in Node.js modules, as well as external dependencies while writing your project files.

Run project

To run our project we need to execute the main.js module. Let's create a new shell and execute it there:

const shell = emulator.shell.create();
const serverCommand = await shell.runCommand("node", ["main.js"]);
 
const { url } = await emulator.preview.getByShellId(serverCommand.id);
 
// Preview Iframe to see output of code
const previewIframe = document.getElementById("nodebox-preview-iframe");
previewIframe.setAttribute("src", url);

You can use the same shell to control the process it's running (e.g. observe its stdout/stderr, terminate or restart it).

Check out this Nodebox example starter and happy coding!