Guide · Agent skill
How to use the Persistent smolvm dev machine agent skill
Updated · written with AI from the project's own documentation and checked against our catalogue data
The dev-env skill is a set of instructions and scripts that lets an AI agent create and keep a small isolated Linux machine, a smolvm VM, with your development tools already installed. You can stop the machine and come back later without reinstalling everything. This guide explains what the skill does, how to install it, how to trigger it with plain requests, and what it needs and risks before you run it.
Quick start
- 1Install the skill. Download the ZIP from this page and unzip it into ~/.claude/skills/ or the project's .claude/skills/ folder, or upload it under Settings, Capabilities, Skills.
- 2Check your requirements. Confirm smolvm is installed on the host, that you have a bash shell, and that you are on macOS or Linux.
- 3Write or pick a Smolfile. Start from the skill's Smolfile, keep one-time setup in init, and put every-boot work in the commands that need it.
- 4Create and start the machine. Run the create script from your project directory and check that it reports result=up.
- 5Install dependencies. Use machine exec to install packages as the Smolfile user, and use --user root only for system changes.
- 6Verify persistence. Run the persistence script, which compares installed package versions and file values across a stop and start.
- 7Clean up when finished. Run the cleanup script with --purge only when you no longer want the machine.
What the dev-env skill makes the agent do
The skill teaches the agent to create a named smolvm machine, install dependencies once, and re-enter the same machine in later sessions. Its central rule is that init runs once, on the first start, and not on every start. Anything that must hold on every boot has to run in the command that needs it.
The skill also covers what files survive a restart. Packages installed with pip --user, files under $HOME and files written at / persist, while /tmp is emptied at each start and /storage persists. It includes a preflight check, a script that creates the machine, a persistence test and a cleanup script.
Install the dev-env skill
Download the dev-env ZIP from this page and unzip it. For a personal setup, unzip it into ~/.claude/skills/. For a single project, unzip it into that project's .claude/skills/ folder. In the Claude apps, you can instead upload the ZIP under Settings, then Capabilities, then Skills.
After installing, check that the folder contains SKILL.md at its top level, since that file is what describes the skill to the agent.
- Personal: ~/.claude/skills/
- Per project: .claude/skills/ inside the project directory
- Claude apps: Settings → Capabilities → Skills, then upload the ZIP
What you need before you start
You need smolvm installed on the host. The scripts are bash scripts, so you need a bash shell. The skill was tested on macOS arm64 and Linux aarch64. On Windows, the preflight check reports unknown, and the separate Windows reference notes differ, so treat Windows as a less certain path.
You also need a Smolfile and a project directory. The example Smolfile mounts ./src, which is relative to the directory you run the script from. The scripts create ./src if it is missing. The machine uses network access, and the scripts run commands on your host.
- smolvm installed on the host
- bash shell for the scripts
- A Smolfile and a project directory
- Network access, which the machine uses
Declare the machine in a Smolfile and separate init from per-boot work
The skill's starting Smolfile sets the image, network, CPUs, memory, a volume mount, init commands, and the user and workdir. Setup steps that only need to happen once go in init. Because init runs as root regardless of user, the user line only affects exec and shell.
Commands that must run on every boot, such as a bind mount, belong in the command that needs them rather than in init.
image = "python:3.12-alpine"
net = true
cpus = 2
memory = 2048
volumes = ["./src:/app"]
init = [
"sh -c \"id -un > /init-ran-as.txt\"",
"sh -c \"date +%s >> /init-count.txt\"",
"adduser -D app",
]
user = "app"
workdir = "/app"Create the machine and bring it up
Run the create script from the project directory. With no arguments it uses the default name smolskill-dev. You can pass a name and a Smolfile path. The script creates the machine with a long-lived workload command, starts it, waits for the workload to answer, and reports what actually happened.
A good result shows init_ran=yes, machine_running=yes, workload_ready=yes and result=up. Seeing init_ran_as=root alongside exec_user=app is correct, because init provisions as root while exec runs as the Smolfile user.
scripts/create-dev-machine.sh
scripts/create-dev-machine.sh smolskill-myproj ./my.smolfileWork in the machine and prove the setup persists
Use exec to run one command as the Smolfile user, use exec with --user root for system changes, and use shell for an interactive session that starts in the workdir. When setup is done, stop the machine and note its name. The next start brings it back as it was.
The persistence script installs a package, records its version, seeds one file on each filesystem, stops and starts the machine, then checks each value. Compare versions rather than relying on an import succeeding, because an import can be satisfied by a system copy of the package.
smolvm machine exec --name smolskill-dev -- pip install --user requests
smolvm machine exec --name smolskill-dev --user root -- sh -c 'mkdir -p /storage/keep'
smolvm machine shell --name smolskill-dev
scripts/verify-persistence.shKnow what survives a stop and start
Persistence depends on where a file lives. The root filesystem is an overlay stored on the machine's disk, so writes under / survive. /tmp does not survive, because it is emptied at each start.
- pip --user packages: survive
- Files under $HOME: survive
- Files written at /: survive
- /tmp: does not survive
- /storage/...: survives
Safety notes: scripts, network and mounts
The scripts wrap the public smolvm command line. They do not edit smolvm configuration or anything under ~/.smolvm. Cleanup deletes only machine names it recorded with the smolskill- prefix.
A volumes mount gives the guest access to that host directory, so mount the narrowest directory that works and use :ro for read-only needs. Do not set user to root just to make a mount writable, because root in the guest gets everything the mount exposes. net = true gives the whole machine outbound access, so use --allow-host if the machine only needs a package index.
Do not use this skill for untrusted or unknown code. That needs a throwaway machine that leaves nothing behind, which this skill does not provide. Do not use it to run a Docker daemon inside the machine either.
Clean up when you no longer need the machine
Do not clean up at the end of a normal setup, because the machine is the deliverable. Run the cleanup script only when the machine is no longer wanted. It waits up to 20 seconds for the machine list to update before finishing.
scripts/cleanup.sh --purgeWhat people use it for
- Keeping a project's Python or Node dependencies between work sessions without reinstalling them each time
- Debugging a package that disappeared after a machine restart by checking which filesystem it was written to
- Writing a Smolfile and deciding which setup steps belong in init and which must run on every boot
- Recovering when exec reports that the container smolvm-<hash> is not running, by giving the machine a long-lived workload command
Frequently asked questions
How do I install the dev-env agent skill?
Download the dev-env ZIP from this page and unzip it into ~/.claude/skills/ for personal use, or into a project's .claude/skills/ folder for one project. In the Claude apps you can upload the ZIP under Settings, then Capabilities, then Skills.
What do I need to run the dev-env skill?
You need smolvm installed on your host, a bash shell for the scripts, and a Smolfile plus a project directory. The skill was tested on macOS arm64 and Linux aarch64. Its preflight check reports unknown on other platforms such as Windows.
Is the dev-env skill free?
The skill is published under the Apache-2.0 licence, as listed on this page. Check the licence file in the repository for the full terms.
Why did my package disappear after a restart?
Packages installed under /tmp are lost, because /tmp is emptied at each start. Install into $HOME, with pip --user, or write to /storage, which persists. Then run the persistence script to confirm.
Why does exec say the container smolvm-<hash> is not running?
This can happen when exec runs right after start before the machine has a long-lived workload. The create script gives the machine an explicit workload command so that exec answers reliably. The skill's traps reference covers this case.
Can I use this skill to run untrusted code?
No. The skill says untrusted code needs a throwaway machine that leaves nothing behind, and this skill does not provide one. It also does not cover running a Docker daemon inside the machine.
New agent skills, repos and AI tools — every week
The best new skills and open-source projects, the fastest-growing repos, and one free prompt. Five minutes to read. Unsubscribe anytime.
Our verdict
Use this skill if you want a repeatable, isolated project environment whose dependencies survive stop and start, or if you are working out what belongs in a Smolfile's init. Pick a different tool if you need to run untrusted code, need a Docker daemon inside the machine, or are on a platform outside macOS and Linux.
Download the skill