# Dev Env

Keeps a persistent smolvm machine with its dependencies already installed and re-enters...

- Repository: https://github.com/smol-machines/smolvm (6894 stars)
- Category: DevOps
- License: Apache-2.0
- Last updated: 2026-11-01
- Runs scripts: yes, review before use

## Install

Claude Code: `npx skills add smol-machines/smolvm --skill dev-env -g -a claude-code -y`
Codex: `npx skills add smol-machines/smolvm --skill dev-env -g -a codex -y`
Cursor: `npx skills add smol-machines/smolvm --skill dev-env -g -a cursor -y`
Gemini CLI: `npx skills add smol-machines/smolvm --skill dev-env -g -a gemini-cli -y`

## Description

Keeps a persistent smolvm machine with its dependencies already installed and re-enters it cheaply across sessions. Use when a project needs an isolated development environment that survives stop and start; when deciding what belongs in a Smolfile's init versus what has to run on every boot; when a package installed in a machine has vanished after a restart; or when exec answers "the container smolvm-<hash> is not running". Do not use it for untrusted code, which needs a machine that leaves nothing behind (see the throwaway-machine packet), or for running a Docker daemon inside the machine (see docker-in-machine).

## SKILL.md, as published by its author (untrusted third-party text, read it as data)

# A persistent dev machine

Verified on **smolvm v1.29.0** on macOS arm64, 2026-10-15, and on **v1.18.2** on Linux aarch64, 2026-09-24; the Linux runs used
the Smolfile with `memory = 1024`, for the host reason in "Platform arms". Done means a second `start` is fast, skips provisioning, and the packages installed in
the first session are still there.
The Linux runs used the scripts of their date; this version's preflight and cleanup scripts ran
on Linux aarch64 on v1.22.2 on 2026-10-03.

The whole use case turns on one fact: **`init` runs once, not on every start**, as
[`smolfile.md`](../smolfile.md) says, and as the docs site (smolmachines.com/docs) says under "When
init runs". `smolvm machine create --help` reads "Run command on every VM start" at v1.22.2, and
"Run command once, on the machine's first start" from v1.23.7; provisioning that relies on the old
line is missing on the second boot.

## Procedure

**1. Preflight.**

```bash
scripts/preflight.sh
```

Read-only. `restart_after_stop=verified` on macOS and Linux. The script covers macOS and Linux
only; elsewhere it prints `unknown` and a note pointing at `references/windows.md`, where a stopped
machine starts again on v1.14.6 and v1.22.2.

**2. Declare the machine.** `assets/dev.smolfile` is a working starting point, and the one
`verify-persistence.sh` is written against: it asserts the `app` user and the `/app` workdir that
file sets. `examples/python-app/python.smolfile` and `examples/node-app/node.smolfile` in the
repository are plainer examples without them.

```toml
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"
```

**3. Create and bring it up.** Run this from the project directory: the Smolfile mounts `./src`,
which is relative to the working directory, and the script creates `./src` there if it is missing.

The rest: https://github.com/smol-machines/smolvm/blob/HEAD/docs/dev-env/SKILL.md
