Before you start
Stack is a thin orchestration layer; two other things do the heavy lifting and must be on your PATH:
- Phantom Secrets — handles credential persistence.
Real
stack addneeds its supported project setup. - Bun 1.2+ — required by the recorded public CLI/MCP packages 0.1.1. Reviewed source 0.2.1 and historical native 0.2.0 are separate artifacts. Node/npm/npx alone do not prove the public binaries can run.
1. Install Stack
One-liner:
curl -fsSL stack.ashlr.ai/install.sh | bash Or via your package manager:
bun add -g @ashlr/stack@0.1.1
# or (Bun 1.2+ still required)
npm i -g @ashlr/stack@0.1.1 And Phantom (required for anything that touches secrets):
brew install ashlrai/phantom/phantom
# or
npm i -g phantom-secrets 2. Verify the install
stack --version
stack --help
stack status Illustrative local status; inspect your actual report:
Ashlr Stack
● .stack.toml missing — run `stack init`
● phantom 0 secrets in vault
● services 0 configured Status reports local metadata and slot presence. An indicator alone does not prove provider access or usable application credentials.
3. Initialise a project
Inside any repo (Next.js, Astro, Rails, whatever):
cd path/to/your-app
stack init --noInteractive
This writes a blank config; add services one at a time. Interactive
stack init offers a template picker. A selected template
runs provider setup by default unless --noProvision is supplied.
Illustrative interactive output:
┌ stack init
│
◇ Pick a starter template (or blank):
│ Blank — add services later with `stack add`
│
└ Wrote .stack.toml (stk_8f3c6a2e). Two files appear on disk:
-
.stack.toml— committed. The shape of your stack. -
.stack.local.toml— gitignored automatically. Your project_id and per-developer instance data.
Stack attempts to append .stack.local.toml to your .gitignore.
Writes can partially fail; inspect files before sharing. See the config
reference for the full schema.
4. Add your first service
Let's wire up Supabase — the most interesting one, because it has a full upstream provisioning flow plus an MCP server.
stack add supabase For authorized Supabase setup, the adapter attempts:
- Authenticate using the available Supabase OAuth or PAT branch.
- Create a project in an accessible organization, or attach to a requested existing resource.
- Handle resource-critical credentials through managed persistence phases.
- Fetch the anon + service-role keys and route them into Phantom.
- Write an available
supabaseMCP descriptor to.mcp.json; client startup and credential setup remain separate. - Write the service into
.stack.toml+.stack.local.toml.
Illustrative successful output, not a provider acceptance receipt:
┌ stack add supabase
│
◇ ● supabase (abcdefghijklmnop) · 3 secrets · mcp wired
│
└ ✓ supabase is live. 5. Sanity-check with doctor
Before you move on, run stack doctor and inspect the checks
it implements. Some adapters have no health check; a successful report
does not prove every provider or app works:
stack doctor ┌ stack doctor
│
◇ ● supabase (illustrative check result)
│
└ All services healthy.
Run this before deploys, after a stale laptop comes out of a drawer, or any
time something feels off. In CI, use stack doctor --json —
exit code 0 if no reported errors, 1 for reported failures.
Unchecked services still need separate verification.
See CI integration.
6. Forward your app command to Phantom
Instead of bun dev, run stack exec -- bun dev.
The wrapper forwards the command to installed Phantom. Configure the
app's required inputs and verify them separately:
stack exec -- bun dev
Your app may need SUPABASE_URL, SUPABASE_ANON_KEY,
and SUPABASE_SERVICE_ROLE_KEY. Stack does not automatically
write populated env files or guarantee those values reach the app.
Use stack env export --example for an empty-key skeleton.