Runs Python in a local, hardware-isolated micro-VM that keeps its state between calls
Hyperlight is a lightweight Virtual Machine Manager (VMM) designed to be embedded within applications. It enables safe execution of untrusted code within micro virtual machines with very low latency and minimal overhead.
We are a Cloud Native Computing Foundation sandbox project.
Run ordinary Linux programs (e.g., Python, Node.js, .NET, Java, Go, Rust, C, Bash) inside Hyperlight micro-VMs, using a Unikraft unikernel as the guest kernel.
hyperlight-unikraft ships as both a Rust library and a CLI. hluk (the CLI, pronounced "hulk") boots the kernel, mounts a rootfs, runs your workload behind a default-deny host boundary (no filesystem or network unless you opt in), and can snapshot a warmed guest to skip startup on later runs. The same building blocks (SandboxBuilder, run, snapshot save/restore) are exposed as a library, so you can embed guest execution in your own application (hluk itself is a good reference consumer of it).
# 1. Install the CLI (the Unikraft kernel is baked into the binary): Linux, macOS
curl -fsSL https://raw.githubusercontent.com/hyperlight-dev/hyperlight-unikraft/main/install.sh | sh
# Windows (PowerShell)
irm https://raw.githubusercontent.com/hyperlight-dev/hyperlight-unikraft/main/install.ps1 | iex
# or, with a Rust toolchain: cargo install hyperlight-unikraft
# main's latest build that passed CI: HLUK_VERSION=dev in front of either
# 2. Start a project from a template; the matching rootfs is pulled from GHCR
hluk init hello --template python # or plain `hluk init` to be asked
cd hello
# 3. Run it inside a micro-VM
hluk run # boots the guest and runs main.py
hluk run # restores the warm snapshot the first run saved: milliseconds
# Or skip the project: a published image by name, warm by default
hluk run --runtime python examples/python/hello.py
hluk templates lists what init can start from: a script for Python (plain, or with a BusyBox shell to call through subprocess), Node.js, QuickJS, Bash, C# (compiled in the guest by Roslyn), Java (run by JShell in the guest) and PowerShell; an interactive BusyBox shell (bash-repl); a compiled program for Go, Rust, C and .NET Native AOT, or a Rust program compiled to a WebAssembly component that Wasmtime runs in the guest (hluk build runs the compiler, hluk run mounts the result); an HTTP server on a rootfs you extend with pip, npm or the .NET SDK through a Dockerfile (hluk build builds it with Docker); and the agent image with numpy, pandas, scipy and scikit-learn preloaded. --template also takes a template of your own, a directory or github.com/OWNER/REPO[/PATH][@REF]; docs/templates.md shows how to write one, from examples/templates/word-count. The project's hluk.toml says what runs and with which capabilities; docs/manifest.md is the reference.
Without a project, hluk run takes the same settings as flags (--initrd, --mount, --net, --net-allow, --net-block, --port, --exec, --scratch-mb, …), and hluk snapshot save / hluk snapshot run save and restore a guest by hand; hluk --help has the full set. To build a rootfs from this repository's recipes instead of pulling one, just build-rootfs python (needs Docker and just) writes build-elfloader/python-rootfs.cpio, which hluk run --initrd or a manifest's [rootfs] path takes. The just recipes (just run <runtime> <script>, just snapshot-save, just bench) wrap a locally built ./target/release/hluk, which is handy when developing on the repo.
hyperlight-unikraft runs on Linux (KVM, or MSHV with cargo build --features mshv), Windows (WHP), and macOS on Apple silicon (HVF). On an arm64 host it embeds an arm64 kernel and runs arm64 guests; every published runtime image carries both architectures. Releases have no Windows arm64 hluk yet: build main there (git clone https://github.com/hyperlight-dev/hyperlight-unikraft, then cargo install --locked --path . inside it, which picks up its pinned toolchain; the build needs none of the kernel's submodules), with Visual Studio's clang on the PATH for ring. On macOS the hluk binary needs the hypervisor entitlement: codesign -f -s - --entitlements dev/macos-entitlements.plist target/release/hluk (cargo run and cargo test do it for you, install.sh signs the one it installs, and an unsigned hluk prints a command that signs it). Hypervisor.framework allows one VM per process, so the sandboxes of one process take turns: run them from separate processes to run them side by side. A guest waiting on a timer while another sandbox runs sees its deadline pass.
Guest runtimes include Python, Node.js, .NET (JIT and AOT), Java, Bash, Go, Rust, C, PowerShell, QuickJS and Wasmtime (WebAssembly modules and components under WASI). The quickjs, node, python, dotnet-jit, java and wasmtime images also take guest function calls (a handler defined once, called many times with JSON in and out) and make host function calls to functions you provide, like hyperlight-js and hyperlight-wasm; see docs/calls.md. Two are Python variants with a BusyBox shell: python-shell (Python + a shell; a general base other images build on) and agent (python-shell plus preloaded data-science packages like numpy, pandas, scipy, scikit-learn, which are commonly used for agent code-executors). Any Python guest with --net can also pip install packages on demand from inside the guest (see examples/agent/pip_install.py). See support tiers for the guarantee behind each; just list-runtimes prints the current set.
python-shell can also boot into the shell rather than the Python driver, with --entry (--guest-exec runs its file with Python). The mount puts your files in the guest, and an entry point starts with PATH=/bin while python3 lives in /usr/local/bin, so set PATH or call /usr/local/bin/python3:
| To | Run |
|---|---|
| Run Python through the shell | hluk run --runtime python-shell --mount .:/mnt/app:ro --env PATH=/usr/local/bin:/bin --entry "/bin/sh -c 'python3 /mnt/app/main.py'" |
| Run a shell script | hluk run --runtime python-shell --mount .:/mnt/app:ro --env PATH=/usr/local/bin:/bin --entry "/bin/sh /mnt/app/script.sh" |
| Open a shell REPL on stdin (Ctrl-D leaves) | hluk run --runtime python-shell --mount .:/mnt/app:ro --env PATH=/usr/local/bin:/bin --entry /bin/sh |
The shell is BusyBox's hush, not bash: POSIX scripts, pipes and $(...) work, bash arrays and [[ ]] do not.
Guest scripts under examples/ run with hluk run (or just run <runtime> <script>):
examples/http-server/{flask,express,kestrel}/ also show how to build a custom guest image on top of hluk's base runtime rootfs images (Python, Node, .NET AOT); see e.g., examples/http-server/flask/Dockerfile. The http-python, http-node and http-dotnet templates of hluk init are the same three as projects.examples/python/threading_demo.py and examples/python/subprocess_demo.py exercise guest threads and subprocesses.examples/agent-framework/ runs a Microsoft Agent Framework agent with fully offline llama.cpp inference (local.py) or a remote model call (remote.py).Larger, self-contained demos live under demos/, each with its own Justfile and README.md (Linux):
demos/supply-chain/ — a typosquat supply-chain attack, contained by the VM.demos/pptx-gen/ — LLM-written python-pptx code run in a sandbox to build a .pptx.demos/urunc/ — deploy a guest through urunc and containerd.integrations/smolagents/ is smolagents-hyperlight, released to PyPI: a code executor that runs a CodeAgent's code in a micro-VM, with no network unless allowed, ready in about 40 ms on Linux with KVM (CodeAgent(..., executor=HyperlightExecutor())).integrations/mcp/ is mcp-server-hyperlight, released to PyPI: an MCP server whose run_python tool runs Python in a micro-VM that keeps its state between calls, for Claude Code, Claude Desktop, VS Code, Cursor and other MCP clients (claude mcp add hyperlight -- uvx mcp-server-hyperlight).integrations/clickhouse/ is clickhouse-hyperlight, a driver for ClickHouse's driver-based UDFs: any user can write a function in Python (CREATE FUNCTION ... ENGINE = HyperlightPython AS 'return len(s.split())'), and each block of rows runs in a micro-VM restored from a snapshot in about 1.5 ms, with no network and none of the server's files.hluk embeds the Unikraft elfloader kernel and maps a rootfs CPIO (the guest userland) as the initrd.--mount preopens a host directory, --net (with optional --net-allow/--net-block lists) enables networking, and --port lets the guest listen.More details are in docs/: projects, the manifest and the published images (manifest.md), how a guest is driven and the ways to run one (execution.md), the contract between a runtime driver and the kernel (driver.md), the host filesystem sandbox (fs.md), guest networking (net.md), guest concurrency and snapshot restore (concurrency.md), the guest's clocks (clock.md), its random source (random.md) and where a sandbox's time goes (profiling.md).
just build-all-rootfs # build every guest rootfs
just test # unit + integration tests (need the rootfs CPIOs)
just conformance python # run a tier-1 runtime's upstream test suite
just ci # lint, license headers, tests, and demo smoke tests
Cold start, snapshot-restore latency, and throughput are measured on every merge to main for tier 1 runtimes, with trends published to GitHub Pages.
Please review CONTRIBUTING.md for how to contribute.
We hold weekly community meetings, open to everyone.
The Hyperlight project Slack lives in the CNCF Slack #hyperlight channel. Join the CNCF Slack, then join #hyperlight.
For the broader project, see the main Hyperlight repository.
See the CNCF Code of Conduct.
Licensed under the Apache License, Version 2.0.
Source-derived launch command. Check the maintainer’s required arguments and credentials before running:
uvx mcp-server-hyperlightMerge this template into ~/Library/Application Support/Claude/claude_desktop_config.json. Keep existing servers. Add any arguments, credentials, and permissions required by the maintainer; this template has not been install-tested.
{
"mcpServers": {
"io-github-hyperlight-dev-mcp-server-hyperlight": {
"command": "uvx",
"args": [
"mcp-server-hyperlight"
]
}
}
}Restart Claude Desktop completely for changes to take effect. Confirm the server appears connected in the client’s tool list, then try a read-only example from its documentation.
Claude Desktop setup referencemcp-server-hyperlightpypiHyperlight works with any MCP-compatible client. Copy the config snippet from the Configuration section above and add it to the file shown for your client, then restart the application.
~/Library/Application Support/Claude/claude_desktop_config.jsonRestart Claude Desktop completely for changes to take effect.~/.cursor/mcp.jsonRestart Cursor for changes to take effect..vscode/mcp.jsonReload VS Code window for changes to take effect.~/.codeium/windsurf/mcp_config.jsonRestart Windsurf for changes to take effect..mcp.jsonSave at the project root, then start Claude Code in that project and review the MCP server approval prompt. Keep real credentials out of shared files.