flisk-build

Turn a plain request such as "build me a small online shop", "a SaaS with login and billing", "an AI agent with MCP tools and a database" or "a blog with an admin API" into Flisk steps (`flisk project

SKILL.md

GitHub

Build an app with Flisk

The user describes an app. Map each part of it to a Flisk resource, let Flisk write the containers, routing and database wiring, write only the app code, and finish with the working URLs.

First: does this app need Docker?

Pick the path before anything else.

  • No Docker (prefer it for a simple app): every part can be started with one command and none needs a database, one gateway URL, or the container it deploys. Examples: an API and a website, a static site and a webhook receiver, an agent that calls an external model API. Follow "Simple app without Docker" below and skip the Workflow.
  • Docker + Tilt: the app stores data in Postgres, needs Redis or another image, or the user asks for the same container they deploy. Follow the Workflow.

A database or cache can run in Docker next to command services: give it an image (no command, no dockerfile) and flisk up starts it with docker run (a mixed run, docs/run-without-docker.md). Any other mix, such as a service built from a Dockerfile next to a command service, is refused with MIXED_RUNTIME.

Simple app without Docker

  1. Write each part as a folder with its own code and a service.json that names the command that starts it: { "schemaVersion": 1, "appName": "api", "appType": "backend", "command": "node server.js", "port": 4000, "healthCheckPath": "/health" }. The command runs from that folder with PORT set. Add "dependsOn": ["api"] to a part that calls another, and pass URLs through "env": { "API_URL": "http://localhost:4000" }. Use the runtime's own watch mode for reload (node --watch server.js, uvicorn main:app --reload --port $PORT).
  2. Run flisk doctor. It checks only that each command's program is installed and the ports and dependsOn are valid.
  3. Run flisk up --json in the background (&) and wait for its one JSON line: "ok":true, "runtime":"native" and urls with each service's http://localhost:<port>. No flisk project or flisk resource step is needed; the first flisk up writes .flisk/project.json.
  4. Request every URL (curl -fsS <url>); each must answer. On a failure read flisk logs --service <name> --tail 100, fix the code, and run flisk up --json again (it restarts a crashed service on its own).
  5. Tell the user what was built, one line per part with its URL, and that flisk down stops it. Guide: docs/run-without-docker.md.

Workflow

  1. Check the machine. Run flisk doctor. If it reports an error, fix what it names (or tell the user what to start, for example Docker) and run it again. Do not continue past an unresolved error.
  2. Plan the parts. Split the request into resources and pick one stack name for all of them (short, kebab-case, from the app: shop, saas, ai, blog). Use the table below. Tell the user the plan in one or two lines.
  3. Create the project in an empty folder: flisk project --yes. If the request matches a starter app (restaurant, SaaS, store, agent stack, user management), clone that instead: see the flisk-recipe-starters skill. In a folder that already has .flisk/project.json, skip this step.
  4. Add each part with flisk resource <name> --type <type> --stack <stack> --yes. Add --feature drizzle (or --feature prisma) to a backend that stores data. Add --framework <id> or --language <id> only when the user names one.
  5. Write the app code inside each resource's src/. Keep the generated /health route. Do not write Dockerfiles, Compose files, Tiltfiles or proxy config, and do not edit .autogenerated/: change service.json instead and Flisk regenerates.
  6. Preview, then start: flisk up <stack> --dry-run shows the services and URLs. Then run flisk up <stack> --json in the background (&) and wait for its one JSON line: "ok":true means the stack is ready. A cold first build can take a few minutes.
  7. Check every URL. Get them with flisk networks --stack <stack> --raw (or --json) and request each health URL (curl -fsS <url>). Every one must answer 200. For a backend with a database, also request <base>/health/db.
  8. When something fails, run flisk doctor, then flisk logs -s <resource> --tail 100 for the failing resource. Fix the source (app code or service.json), and the running stack reloads. If a build failed, run flisk up <stack> --json again. Follow the flisk-troubleshoot skill for messages you do not recognise. Stop after three failed attempts at the same error and tell the user what you saw. If Docker says all predefined address pools have been fully subnetted, old projects still hold their networks: run flisk doctor --fix here and flisk down --prune-networks in projects the user no longer runs (ask first), then start again.
  9. Tell the user, in plain words: what was built, one line per part with its URL, how to try it (an example curl or "open this in your browser"), and that flisk down stops everything.

From request to resources

The user asks for Resource Command
A website, storefront, dashboard, admin page frontend flisk resource web --type frontend --stack <stack> --yes
An API (orders, posts, users, billing) backend flisk resource orders-api --type backend --stack <stack> --yes
Something that stores data, "a database" backend with a database feature flisk resource notes-api --type backend --stack <stack> --feature drizzle --yes
Background jobs, emails, imports worker flisk resource jobs --type worker --stack <stack> --yes
An AI agent, chatbot, assistant agent flisk resource assistant --type agent --stack <stack> --yes
Tools for an agent, an MCP server mcp flisk resource tools-mcp --type mcp --stack <stack> --yes
An admin panel or back office next to the main site a second frontend flisk resource admin --type frontend --stack <stack> --yes
Several APIs ("3 APIs") one backend each flisk resource catalog-api ..., flisk resource orders-api ... (keep it to three or fewer)
A cache, Redis bring-your-own flisk resource cache --type bring-your-own --image redis:7 --no-proxy --stack <stack> --yes
Chat, live updates, websockets backend an ordinary backend; write the websocket route in its code
An existing image (Mailpit, a vendor's server) bring-your-own flisk resource mail --type bring-your-own --image <image> --stack <stack> --yes
A third-party API (payments, a shop platform) backend that holds the key list the key's name under secrets.required in its service.json, put the value in the project .env, and call the vendor only from that backend
Python or Go backend with a language flisk resource api --type backend --language python --stack <stack> --yes (or go)
A frontend framework by name (Vue, Svelte, Solid...) frontend with a framework flisk resource web --type frontend --framework vue --stack <stack> --yes (list them: flisk resource --type frontend --frameworks)

Web3 apps (a local chain node and contracts) are not covered: no Flisk recipe has run a chain node end to end. Say so instead of improvising one.

Every stack gets the shared Postgres database: you do not add one. A backend created with --feature prisma gets a DATABASE_URL, a Prisma schema, and a <name>-migrator resource that applies migrations before the API starts. A backend created with --feature drizzle gets a DATABASE_URL, a Drizzle client in src/db.ts and a /health/db check, but no migrator.

Name APIs <thing>-api. Flisk drops the -api suffix in the route, so orders-api is served at /api/orders. Backends are served on api.<project>.localhost and frontends on app.<project>.localhost, where <project> is the project name (by default the folder name) and the port is the one flisk up picked. Read the real URLs from flisk networks; do not build them by hand.

Tables

The Flisk convention is a separate migrator that creates and changes tables before the APIs start. --feature prisma scaffolds one for you (<name>-migrator); for other tools see one-shot jobs. For a quick prototype, creating tables with CREATE TABLE IF NOT EXISTS when the API starts also works; say which one you used.

Recipes

Ready-made plans for common requests: flisk-recipe-starters (clone a working starter app), flisk-recipe-shop, flisk-recipe-saas, flisk-recipe-ai-agent and flisk-recipe-blog. More prompts by category (spreadsheets, recruiting, product management, internal tools) are in docs/recipes/build-with-your-agent.md.

Guardrails

  • Use only the flags in flisk <command> --help. Do not guess flags.
  • Report a URL as working only after it answered 200. If one never did, say so and say what the logs showed.
  • Ask before running flisk up -f: it stops a Tilt process that is already running.
  • Ask before adding services the user did not ask for. One frontend and one API is enough for "a small" app.
  • Flisk runs the app on this machine. It does not deploy it.