# create-shibumi CLI
Every template deploys to a Linux VPS through `shibumi-server`.
## Create a project
Three questions, then the project exists:
```clack
bun create shibumi@latest my-app
渋み shibumi
success|Project name?
answer|quiet-bamboo
success|What are you shipping?
answer|Bun full-stack app (recommended)
success|Deploy to a VPS now?
answer|Later
result|Created quiet-bamboo
success|Template copied
success|Git initialized; nothing committed, the first commit is yours
success|Dependencies installed
success|Deploy script added (scripts/ship.ts)
info|Next: cd quiet-bamboo, bun dev, and bun ship:setup when you're ready
outro|Docs: https://shibumistack.dev/docs
```
Answering **Yes** to the deploy question runs `bun ship:setup` in the same session, so the project's first deploy happens before you leave the terminal. **Later** prints the command instead.
Automation skips the questions:
```sh
bun create shibumi@latest my-app --template full-stack --yes
```
`--template` takes `full-stack`, `blog`, or `static`. `--no-git` and `--no-install` skip those steps. VPS deployment only (for now); provider choices stay out until generated fixtures prove each build and deploy path.
## Add deployment to an existing project
A dot instead of a name adopts the current directory. Instead of scaffolding, the deploy script is copied in next to your own files. Your existing files are left as they are, with one exception: `package.json` gains the `ship*` scripts and a `@clack/prompts` dev dependency, since the deploy script imports it.
```clack
bun create shibumi .
渋み shibumi
info|Existing project found (Astro detected)
success|Add deploy tooling to this project?
answer|Yes
success|Built site directory?
answer|dist/ (detected)
success|Wrote scripts/ship.ts, package.json, Dockerfile, compose.yaml, .dockerignore
success|Added scripts: ship, ship:setup, ship:update, ship:status, ship:logs, ship:webhook
result|Installed @clack/prompts
success|Deploy to a VPS now?
answer|Later
info|Deployments serve dist/. Review the generated Dockerfile and compose.yaml.
outro|Docs: https://shibumistack.dev/docs
```
The build directory is detected from your dependencies and config files, with the framework signal winning over a directory that happens to be on disk:
| Signal | Directory |
| --- | --- |
| `astro` or `astro.config.*` | `dist` |
| `@11ty/eleventy` or `eleventy.config.*` | `_site` |
| `next` or `next.config.*` | `out` |
| `vite` or `vite.config.*` | `dist` |
| a `dist`, `_site`, `out`, or `build` directory | that one |
| a `public` directory | `public` |
A dependency or a config file counts as the same signal. Astro and Eleventy both pull Vite in, so a bare Vite match loses to either of them.
Pick **Somewhere else** to type a path the table missed. `--spa` makes unknown paths serve `index.html`; without it, unknown paths 404, which is what a content site wants.
Adopting refuses in three cases rather than guessing:
- **Deployment files already exist.** A `Dockerfile` or `compose.yaml` that Shibumi did not write may build or run something other than your site, so adopting stops and asks you to remove or rename them.
- **The project is a server app.** A `start` script means something runs inside the container, and that is `bun ship:setup`'s job: it asks server or static and writes the matching files. To ship a static build from a project that also has a `start` script, run `bun ship:setup --static --output-dir
`.
- **`index.html` sits at the project root with no directory to serve.** The table above found nothing, so the site is a flat pile of files at the root. A static image serves one directory and never packages a whole checkout, so move the site down a level with `mkdir public && git mv index.html public/`, then adopt again. A project with a detected build directory adopts normally, root `index.html` or not.
Without a build script, the output directory has to be committed already, so the shipped image matches the exact commit the server verifies.
## Shared project contract
Generated projects import their libraries directly. Each applicable project includes:
- route or artifact tests and TypeScript checks
- root `agents.md` guidance
- current reviewed `scripts/ship.ts`
- loopback-only Compose configuration, resource limits, and a health check
- package commands for development, setup, status, logs, rollback, and shipping
Project creation initializes Git only when selected. It never stages or commits user files. Existing paths are never overwritten silently, and failed creation leaves the destination absent or unchanged.
## Static sites
Static publishing depends on an artifact contract rather than a framework adapter:
- output path must be relative and remain inside project root
- build must produce `index.html`
- missing or empty output fails before packaging
- normal file and `404.html` handling is default
- SPA fallback is explicit, never inferred
Shibumi packages the verified directory in a small static image and checks `/` before deployment. A framework's source `public/` directory does not count unless it is also the completed output.
## Blog
The blog template runs on the same engine as this site — a Bun + Hono markdown renderer — with the parts a blog needs on day one: posts in Markdown, RSS, a sitemap, SEO meta tags, and an `llms.txt` for agents. It builds to `dist/` and ships through the same static path, so `bun ship:setup` arrives pre-configured.
## Full-stack SQLite
A full-stack project stores its database under persistent `/data` and enables WAL mode, foreign keys, and a bounded busy timeout. It includes tracked migrations, a fresh-database migration test, pre-migration backup, backup retention, and an explicit restore command.
> **Important:** Image rollback does not reverse a database migration. Generated guidance requires backward-compatible migrations and a reviewed restore path before destructive schema changes.
The project includes database infrastructure and tested queries without an unauthenticated demo mutation endpoint.
## Release acceptance
Tests run against the packed npm artifact, not repository source. Every starting point passes its applicable matrix:
```sh
bun install --frozen-lockfile
bun test
bun run check
bun run build
```
Static output must package only the configured artifact. Bun containers must start on the assigned loopback port and pass their health URL. Full-stack deployment must preserve SQLite data across container replacement and prove backup and restore behavior.
Release checks use a disposable VPS fixture for setup, exact image upload, deployment, health, status, logs, and rollback.
## Extensions
Full-stack projects include the versioned extension command. Add bundled auth, email, or uploads source with:
```sh
bun shi add auth
```
The command previews writes, stops on conflicts, records a named guide under `agents/`, and does not duplicate files when repeated. Auth and uploads need the full-stack database; uploads also needs auth installed first.
## Deferred
Cloudflare, Vercel, Fly.io, background jobs, payments, admin, and a public extension registry remain planned. They stay out until fixture projects can install, build, run, and deploy them without special cases.
Working server commands are documented in [Server commands](/docs/reference/server-commands).