Skip to content

CLI Init Flow

This guide explains exactly what happens when you run:

Terminal window
npx seamless-cli my-app

That project-name shorthand runs the same init path as npx seamless-cli init my-app. Running the CLI with no command prints help.

This guide focuses on local project generation, auth wiring, Docker setup, and admin dashboard inclusion.


init → prompts → generators → config → ready-to-run app

If you pass a project name:

Terminal window
npx seamless-cli my-app

The CLI will:

  • Create a new folder
  • Ensure it does not already exist
  • Use it as the project root

If you run npx seamless-cli init with no project name, it uses the current directory. If that directory is not empty, the current CLI prints that an existing project was detected and exits; the existing-project integration flow is still future work.


The CLI asks a series of questions to shape your stack.

  • React (Vite)
  • Next.js is listed as coming soon, not currently generated

This determines your frontend scaffold.


  • Express
  • Fastify, FastAPI, and Axum are listed as coming soon, not currently generated

This determines your API server.


  • Docker (recommended)
  • Local dev server (advanced)

Docker mode:

  • Runs full auth stack in containers
  • Closest to production

Local mode:

  • Generates the auth server source into ./auth
  • Still relies on Docker for the full local stack
  • Prompts about Docker, but the current source enables Docker either way because it is required for the full generated stack

You choose whether to include the Admin UI.

If enabled:

  • Docker image (recommended)
  • Source (for customization)

Based on your answers, the CLI executes generators.

await generateReactStarter({ root })

Creates:

  • React app (Vite)
  • Auth-aware starter frontend

await generateExpressStarter({ root })

Creates:

  • Express API
  • Auth-ready endpoints

If using local mode:

await generateAuthServer({ root }, 'local')

This generates the Seamless Auth server locally.


await generateDockerCompose(root, {
authMode,
adminMode,
includeAdmin,
})

Creates:

  • Postgres container
  • Auth server container
  • Admin UI container (optional)

The CLI wires environment variables automatically.

configureApiEnv(root, sharedConfig)
configureWebEnv(root)
configureAuthLocalEnv(root)

This ensures:

  • Services can communicate
  • URLs and ports are aligned

generateSeamlessConfig(root, { ... })

Creates:

seamless.config.json

This file stores:

  • Framework choices
  • Auth mode
  • Admin configuration

The CLI prints next steps. In the Docker-backed path, those are:

  • docker compose up
  • seamless bootstrap-admin
  • complete registration in the browser

It also prints the expected local service URLs for auth, API, web, and admin.


my-app/
web/
api/
auth/ # local auth mode only
admin/ # admin source mode only
docker-compose.yml
seamless.config.json
README.md

  • Auth endpoints
  • Session handling
  • Secure cookies
  • Frontend SDK integration
  • Backend auth validation

The CLI chooses:

  • Secure session handling
  • Passwordless flows
  • Best-practice structure

You always get:

  • web/ frontend starter
  • api/ backend starter
  • local Docker Compose wiring
  • seamless.config.json
  • auth server runtime wiring

You may also get:

  • auth/ source when local auth mode is selected
  • admin/ source when admin source mode is selected

Even in local mode, Docker is used to ensure consistency.


  • Running in a non-empty directory
  • Skipping Docker setup
  • Misunderstanding auth mode differences

Copy this into ChatGPT:

“Explain what happens internally when I run seamless-cli init and how the project is generated.”


→ Learn how Docker and local services work together