QUESTPIE

Your first app

One command scaffolds the project, and four more take it to a running admin screen.

View markdown

This page walks you through the scaffolder, the two choices that decide the shape of your project, and the run steps that follow.

Scaffolding the project

create-questpie is the scaffolder. It is its own package, so there is nothing to install first. The argument you give it becomes the directory name.

To create a project, run it with a name:

bunx create-questpie my-app

It refuses to run if my-app already exists. Otherwise, on the default answers, it:

  • copies a template and substitutes your project and database names,
  • writes .env from .env.example with a generated database password and a 48 character BETTER_AUTH_SECRET,
  • installs dependencies with Bun, unless you launched it through pnpm or yarn,
  • installs the questpie and questpie-admin agent skills into the project,
  • runs codegen,
  • commits the result as Initial commit from create-questpie.

Every template Dockerfile builds on oven/bun:1.3-alpine, and the local database runs in Docker.

Answering the prompts

You get up to eight questions when stdin and stdout are both a terminal, one fewer when the name already arrived as an argument. Two of them decide what the project is.

A runtime is the server your app mounts into. Four ship as templates: TanStack Start, Next.js, Hono and Elysia. TanStack Start is the default.

A module is an optional package the scaffolder wires into src/questpie/server/modules.ts. Four are available: admin, openapi, workflows and mcp. The prompt pre-selects the ones that are on by default for your runtime.

PromptDefault
Project namenone, required
RuntimeTanStack Start
Modulesadmin and openapi on a render runtime, openapi alone on a headless one
Database namederived from the project name
Install dependencies?yes
Initialize git repository?yes
Install QUESTPIE agent skills into the project?yes
Run QUESTPIE codegen after installing dependencies?yes

The admin module needs a runtime that renders. TanStack Start and Next are the two render runtimes. Hono and Elysia are headless, so admin is filtered out of their module list, and asking for it by flag fails before any file is written.

The admin does not fall out of the generator

The admin screen is @questpie/admin, a module you enable. Pick Hono or Elysia and you get the REST API and the typed client from questpie, the OpenAPI surfaces from @questpie/openapi, and no admin UI.

Scaffolding without prompts

-y skips every question and takes the defaults. The project name then has to be an argument, and flags override the defaults one at a time.

For example, to scaffold a headless Hono API with MCP and no git:

bunx create-questpie my-api --runtime hono --modules openapi,mcp -y --no-git
FlagWhat it sets
-t, --template <name>, --runtime <id>Runtime. Default tanstack-start.
--module <name>One module. Repeat the flag for more.
--modules <a,b,c>Modules as a comma separated list.
-y, --yesSkip the prompts and take the defaults.
--database <name>Database name.
--queue <adapter>pg-boss, bullmq or none. Default pg-boss.
--email <adapter>console, smtp, resend or plunk. Default console.
--realtime <adapter>none, pg-notify or redis-streams. Default none.
--kv <adapter>memory or redis. Default memory.
--no-install, --no-git, --no-skills, --no-generateSkip that step.
--continue-on-errorKeep the files when install or codegen fails.

Starting the database

QUESTPIE stores everything in PostgreSQL. The template ships a docker-compose.yml with a postgres:17 service on port 5432, matching the DATABASE_URL already written into .env.

To start it, move into the project and bring the container up:

cd my-app
docker compose up -d

The compose file mounts docker/init-extensions.sql, which creates pg_trgm on the first cluster init. questpie push never creates an extension, which is why that file exists. questpie migrate does run CREATE EXTENSION IF NOT EXISTS "pg_trgm" through the default Postgres search adapter, and it fails with a named error when the role may not create extensions. On managed Postgres, enable the extension through your provider before you deploy.

Creating the tables

db:push runs questpie push. It diffs the schema your collections describe against the database and applies the difference in place, with no migration file in between.

bun run db:push

db:push is development only

questpie push writes to the database without recording a migration, so the migration history stops describing the schema. Never run it against production or in deployment automation. --force only acknowledges the warning, it does not make the command safe. For production, commit the output of bun run migrate:create and apply it with bun run migrate.

Running it locally

The dev script runs Vite with --port 3000.

bun run dev

Three URLs serve on that port, and each one comes from a different package:

URLWhat is thereFrom
http://localhost:3000The starter page. Edit src/routes/index.tsx.your app
http://localhost:3000/adminThe admin screen.@questpie/admin
http://localhost:3000/api/docsScalar reference over the REST routes.@questpie/openapi

Open /admin first. No admin user exists yet, so the login page sends you straight to /admin/setup. Give it a name, an email and a password of at least eight characters. That account is created with the admin role, and the setup route refuses to run again once any admin exists.

You now have a database, an API and a screen that reads them. It has one example collection in it.

Next

Add your first collection puts a table of your own into that admin screen.

On this page