# npm Packages

## Install into a VM

Packages install into a VM's filesystem, so they need a [VM](/secure-exec/docs/vms)
that outlives the call.

secure-exec/examples/npm/src/index.ts:

```ts
// 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}`);
	}
```

secure-exec/examples/npm/src/index.ts:

```ts
// 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.

secure-exec/examples/mounts/src/index.ts:

```ts
// 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](/secure-exec/docs/filesystem).
