Use Cases
Dev Servers
Run user-provided HTTP servers and request handlers inside Secure Exec and preview them from the host.
Previews, user-written request handlers, and generated web apps all need code that keeps running and answers requests. Secure Exec runs that server inside a VM and lets your backend talk to it, without opening a port on the host.
Start the server
import { createVm } from "secure-exec";
// The server is user-authored code, so it runs in a VM. Guest listeners stay on
// the VM's virtual network and do not need external network access.
const vm = await createVm();
// `spawn` returns as soon as the process starts, instead of waiting for the
// code to finish. The server prints a line once it is listening, so the host
// knows when it can send requests.
const ready = Promise.withResolvers<void>();
const decoder = new TextDecoder();
const server = await vm.javascript.spawn(
`
import { createServer } from "node:http";
createServer((request, response) => {
response.setHeader("content-type", "application/json");
response.end(JSON.stringify({ path: request.url, pid: process.pid }));
}).listen(3000, () => console.log("listening"));
`,
{
onStdout: (chunk) => {
if (decoder.decode(chunk).includes("listening")) ready.resolve();
},
},
);
console.log("server pid:", server.pid);
await ready.promise;
Proxy requests to it
Forward requests from your own route to the guest, and return what it answers.
// Send requests from the host to the port inside the VM. Nothing is exposed on
// the host's own network.
const response = await vm.network.httpRequest({ port: 3000, path: "/hello" });
console.log(new TextDecoder().decode(response.body)); // {"path":"/hello","pid":...}
- No host port. The server listens on the VM’s virtual network. Only your
process can reach it, through
vm.network.httpRequest. - One VM per preview. Each preview gets its own filesystem and limits.
- Bring a project. Write files with
vm.filesystem, install dependencies with npm, then spawn the entry point.
Stop it
// Stop the server, then dispose the VM.
await vm.process.kill(server.pid);
const exit = await vm.process.wait(server.pid);
console.log("server exited:", exit);
await vm.dispose();
Read more in Long-Running Processes.