Skip to content

Getting started

fend is in alpha and macOS Apple Silicon only. The Linux and Windows ports share the same CLI surface but aren’t shipped yet — see the roadmap on GitHub.

Terminal window
npm install -g @fendsh/cli

This pulls the macOS Apple Silicon binary as an optionalDependency. On any other platform the package fails to install with a clear message.

Verify:

Terminal window
fend --version
# fend 0.1.0-alpha.1

The first fend <anything> invocation downloads the Linux kernel and prepares a rootfs image (~1.5 GB, one-time, cached in ~/.fend/runtime/). It takes a few minutes; subsequent invocations boot the VM in under a second.

In any project with a package.json:

Terminal window
cd ~/repos/my-app
fend npm install

What you’ll see:

fend: auditing 412 package(s) against OSV.dev…
fend: ready (0.8s)
added 412 packages in 28s
312 packages are looking for funding
run `npm fund` for details

Three things just happened:

  1. Audit — fend queried OSV.dev for known advisories against your package-lock.json. If anything critical or malware had surfaced, the install would have been blocked before any script ran.
  2. VM boot — a per-project Linux micro-VM started, mounted your project directory via VirtioFS, and dispatched npm install inside it.
  3. Installnode_modules/ was written by the VM but appears on your host filesystem (so VS Code, TypeScript, ESLint all work natively).

The VM stays warm. The next fend <command> in this project starts in ~5ms.

The simplest mental model. Run fend before any command you want sandboxed:

Terminal window
fend npm install
fend npm run dev # port 3000 forwards back to your host
fend npm test
fend node scripts/seed.js
fend bun install
fend pnpm run build

If you’d rather not type fend every time, install the shell hook once:

Terminal window
# zsh
echo 'eval "$(fend hook zsh)"' >> ~/.zshrc
# bash
echo 'eval "$(fend hook bash)"' >> ~/.bashrc

Then in any project:

Terminal window
cd my-project
fend on # npm/bun/pnpm/yarn/node/python now route through fend
npm install # sandboxed
npm run dev # sandboxed
fend off # back to normal — npm runs natively again

The hook only shims package managers and runtime entry points (npm, npx, bun, bunx, yarn, pnpm, pnpx, node, python, python3, uv, uvx, deno). Everything else (git, ls, cat, your editor) runs natively.

Generate a .fend.toml for the current project:

Terminal window
fend init

This auto-detects the project type (Node, Bun, pnpm, yarn, Python, generic) and writes a sensible default. Every field is optional. See the command reference for the full schema.

Run Claude Code sandboxed:

Terminal window
fend claude # claude with your Anthropic OAuth token injected
# nothing else from your machine reachable

The Anthropic credentials are injected only on this opt-in command, never on the default fend <cmd> path.

Audit only, no install:

Terminal window
fend audit # report against OSV.dev
fend audit --fix # apply safe in-range upgrades + write overrides
fend audit --json # structured output for CI

Inspect a running VM:

Terminal window
fend status # all VMs across all projects
fend stop # stop the VM for the current project
fend clean # destroy VM + per-project state
fend doctor # check kernel, runtime, Docker, config