Skip to main content
Executing Code

npm Packages

Install npm packages into a Secure Exec VM, or mount packages you already have.

Install into a VM

Packages install into a VM’s filesystem, so they need a VM that outlives the call.

// Packages install into a VM's filesystem, so they need a VM that outlives the
// call. Installing needs the network, which is denied unless you allow it.
const vm = await createVm({ permissions: { network: "allow" } });

try {
	const installed = await vm.npm.install(["zod"], {
		output: { capture: "all" },
	});
	if (installed.outcome !== "succeeded") {
		throw new Error(`npm install failed: ${installed.stderr}`);
	}
// Packages install into the working directory, /workspace. A file there
// resolves them the same way it would in Node.js.
await vm.filesystem.writeFile(
	"/workspace/main.mjs",
	`
	import { z } from "zod";
	const parsed = z.object({ name: z.string() }).parse({ name: "secure-exec" });
	console.log(JSON.stringify(parsed));
	`,
);
const ran = await vm.javascript.executeFile("/workspace/main.mjs", {
	output: { capture: "all" },
});
console.log(ran.stdout?.trim()); // {"name":"secure-exec"}
  • Installing needs the network, which is denied until you allow it.
  • Packages install into the working directory, /workspace. Run your code from a file there so it finds them, or set filePath to a path inside /workspace when inline code imports an installed package.
  • vm.npm.install() with no package list installs the dependencies of the package.json in the working directory.
  • vm.npm.runScript and vm.npm.runPackage work like npm run and npx.

Mount packages you already have

If the packages are already on the host, mount them instead. There is no network access and no install step, so it also works in a one-shot call.

// Mount a host directory of packages as the guest's node_modules, so code can
// import packages you already have with no network and no install step. Point it
// at your project's `node_modules` in a real app.
const hostModules = fileURLToPath(new URL("../host-modules", import.meta.url));

const imported = await execute(
	`
	import { greet } from "greet";
	console.log(greet("secure-exec"));
	`,
	{
		mounts: [nodeModulesMount(hostModules)],
		output: { capture: "all" },
	},
);
console.log(imported.stdout?.trim()); // hello, secure-exec

Read more in Filesystem & Mounts.

Edit this page Last updated September 21, 2026