Getting started
Prerequisites
- Node.js 22.6+,
make, Docker. For deploys: Go 1.25+, thepulumiCLI, andgcloudlogged in twice —auth loginandauth application-default login.
1. Install the CLI and the SDK
Until the SDK packages are published, both come from this repo:
git clone git@github.com:RabiaMakhoul/fluffy-chainsaw.git
cd fluffy-chainsaw && go install ./cmd/fluffy-chainsaw # → $(go env GOPATH)/bin, put that on PATH
cd sdk/typescript && npm install && npm run build # build the SDK once
Then in your app ("type": "module" in package.json — the SDK is ESM):
npm install <path-to-clone>/sdk/typescript # @org/fluffy-chainsaw; companions: -storage, -pubsub, -auth
2. Write markers
The SDK is dumb on purpose — db.connect returns a plain descriptor,
never a client; bring your own driver (pg, Drizzle, …).
[!IMPORTANT] The
fluffy-chainsawscanner only parses TypeScript files (.ts,.tsx,.mts,.cts) when scanning the codebase for capability markers. Raw JavaScript (.js,.mjs,.cjs) is not supported for resource discovery.
// src/index.ts
import { db, cloudrun } from "@org/fluffy-chainsaw";
const users = db.connect("users"); // "database `users` must exist"
cloudrun.entrypoint("orders-api", async (_req, res) => {
res.end(`connected to ${users.database}`);
});
3. Tune them in fluffy-chainsaw.yaml
Next to the app (default <dir>/fluffy-chainsaw.yaml):
defaults:
databases: { instance: app-db } # every database lives on this server
databases:
users: { extensions: [pgcrypto] }
instances: # the Cloud SQL server(s) — declared here, no code marker
app-db: { tier: db-custom-1-3840 }
runners:
orders-api:
uses: { databases: [users] }
trigger: { http: true } # public; omit for private (IAM-only)
build: { target: orders-api } # make target that prints the image ref
4. Run locally
fluffy-chainsaw local --deps-only -out .env # containers for deps + a .env with every descriptor
node --env-file=.env src/index.ts
Real-enough substitutes: Postgres, emulators, filesystem buckets — same app
code, only the env differs. Without --deps-only your runners run containerized
too (needs the step-5 Makefile), in dev mode: the repo is mounted at
/repo and each runner runs node --watch, so code edits restart it in-place
— no image rebuild; only fluffy-chainsaw.yaml changes need a re-run.
fluffy-chainsaw local-prune tears it down.
[!NOTE]
--deps-onlyonly spins up Postgres databases and filesystem buckets. If your app uses the Firebaseauth:orrealtime:plugins, the corresponding emulators are not started by--deps-onlyand require running the full containerized mode (fluffy-chainsaw localwithout flags) with a Makefile.
5. Deploy
Runner images build through your make target: a Makefile whose target
prints the image ref as its last stdout line, and a Dockerfile that vendors
the unpublished SDK into the image and follows the local dev-mode convention —
WORKDIR under /repo mirroring your repo layout, exec-form
CMD ["node", "<entry>"] (see runners.md). Then:
fluffy-chainsaw deploy -project <gcp-project> -region <region>
One shot: validates config, builds images, generates the Pulumi program, applies
it. The pipeline owns its plumbing deterministically — state backend
gs://fluffy-chainsaw-state-<project> (created on first use), stack dev, the
documented default passphrase dummy, stack config seeded from the flags, and
every needed GCP API enabled by the program itself, retrying while enablement
propagates. Overrides: PULUMI_BACKEND_URL, PULUMI_CONFIG_PASSPHRASE. A fresh
project needs billing + the gcloud logins, nothing else. Firebase stages run
only for auth/Hosting apps. Individual steps: cli.md.