lumo init
Scaffold a minimal, working starter project that already signs users in with LumoAuth.
lumo init --framework next --dir ./my-app
lumo init --framework express
lumo init --framework fastapi
lumo init --framework go
The generated project has its .env pre-filled with the org slug and base URL from your current credentials (run lumo login first), so it works out of the box. The SDK is installed from the public package registry (npm, PyPI or the Go module proxy). The OAuth client ID is the only field you need to supply yourself — the README in each starter explains where to grab it.
Available starters
| Flag | Stack | What's wired up |
|---|---|---|
--framework next | Next.js 14 (App Router) + @lumoauth/nextjs (npm) | <LumoAuthProvider> in layout, <SignIn /> / <UserButton /> on home, /auth/callback route. |
--framework express | Express + @lumoauth/express (npm) | Session middleware, /auth/login, /auth/callback, /auth/logout, protected /api/me via requireAuth(). |
--framework fastapi | FastAPI + lumoauth[fastapi] (PyPI) | Auth router mounted at /auth, get_current_user dependency. |
--framework go | Go (chi) + github.com/lumoauth/lumo-auth-go | Auth router, session cookie, lumoauth.UserFromContext(ctx) for protected routes. |
These four are the only templates. What each one writes:
| Template | Files |
|---|---|
next | README.md, .env.local, .gitignore, package.json, tsconfig.json, next-env.d.ts, app/layout.tsx, app/page.tsx, app/auth/callback/page.tsx |
express | README.md, .env, .gitignore, package.json, server.js |
fastapi | README.md, .env, .gitignore, requirements.txt, main.py |
go | README.md, .env, .gitignore, go.mod, main.go |
Flags
| Flag | Default | Purpose |
|---|---|---|
--framework | (required) | Which starter to generate. |
--dir | . | Target directory; created if missing. |
--org | (from credentials) | Pre-fills .env. Falls back to the placeholder your-tenant-slug when no credentials are stored. The base URL always comes from the logged-in profile. |
--client-id | (placeholder) | Pre-fills the OAuth client ID in .env. The portal's Quickstarts page includes it in the command it shows. |
--sdk-path | $LUMO_SDK_PATH | Install the LumoAuth SDK from a local source checkout instead of the package registry (see Installing the SDK from a local checkout). |
--force | false | Overwrite existing files. By default, existing files are skipped (with a warning). |
Installing the SDK from a local checkout
By default the starters install @lumoauth/nextjs, @lumoauth/express, lumoauth[fastapi] (PyPI) and
github.com/lumoauth/lumo-auth-go from their public registries. If you are working on the SDK itself,
or need an unreleased change, point lumo init at a LumoAuth source checkout instead — the directory
that contains sdk-js, sdk-python and sdk-go:
lumo init --framework next --dir ./my-app --sdk-path ~/src/lumoauth
# or: export LUMO_SDK_PATH=~/src/lumoauth
| Starter | What --sdk-path does |
|---|---|
next, express | Builds sdk-js if it has no dist/ yet, packs the package and its @lumoauth/* dependencies into ./vendor/*.tgz, and points package.json at those tarballs. |
fastapi | Points requirements.txt at sdk-python (lumoauth[fastapi] @ file://…). |
go | Adds a replace github.com/lumoauth/lumo-auth-go => …/sdk-go directive to go.mod. |
--sdk-path needs npm on PATH for the JavaScript starters (it builds the workspace once if there is no dist/ yet). After changing SDK sources, rebuild (npm run build in sdk-js) and re-run lumo init … --force to refresh the vendored tarballs. The scaffold summary says which source was used (LumoAuth SDK: package registry or LumoAuth SDK: local sources from …).
Every starter listens on http://localhost:3000, whose /auth/callback is pre-registered on the Starter App client.
Example
$ lumo init --framework next --dir ./web
ok README.md
ok .env.local
ok app/auth/callback/page.tsx
ok app/layout.tsx
ok app/page.tsx
ok .gitignore
ok next-env.d.ts
ok package.json
ok tsconfig.json
✓ Scaffolded Next.js 14 (App Router) + @lumoauth/nextjs
Wrote 9 file(s), skipped 0 in /Users/jane/projects/web
LumoAuth SDK: package registry. If the install step cannot find the
LumoAuth packages, re-run with --sdk-path <lumoauth checkout> --force.
Set the OAuth client ID in the .env file before signing in (or re-run with --client-id).
Next steps:
cd ./web && npm install && npm run dev
The "Next steps" line is per starter: npm install && npm start for Express, a venv + pip install -r requirements.txt + uvicorn main:app --reload --port 3000 for FastAPI, and go mod tidy && go run . for Go. Existing files are reported as skip <file> (exists; pass --force to overwrite).
After npm install && npm run dev, visit http://localhost:3000 and click Sign in — you'll be redirected to your LumoAuth organization, sign in, and bounced back to the home page logged in.
What's NOT in the starters
The starters are intentionally minimal. They exist to prove the auth wiring, not to be a production app. You'll add the rest:
- Database layer
- Real protected routes
- A real OAuth client (the templates expect you to register one in the portal and paste the
client_idinto.env) - Session storage (the templates use the framework default — Express's in-memory session, FastAPI's Starlette session, etc.)
- Production logging, monitoring, hardening
Think of lumo init as npx create-next-app -e with-clerk for LumoAuth: it's a starting line, not a finish line.
Getting the OAuth client ID
The starter templates leave one placeholder in .env: the OAuth client ID. The quickest source is the Starter App client that every organization gets at sign-up: it is a public PKCE client that already allows http://localhost:3000/auth/callback and the http://localhost:3000 origin. The portal's Quickstarts page shows a ready-to-run lumo init command with its client ID filled in, and lumo apps list prints the same ID in the terminal.
To use a client of your own instead:
- Open the portal at
https://app.lumoauth.dev/orgs/<your-slug>/portal/applications. - Click New application and enter an Application name.
- Under What the application is, choose Single-page or mobile app for Next.js, or Web application for Express / FastAPI / Go. Either choice sets the grant types to
authorization_code,refresh_token. - Set the Redirect URI:
- Next.js:
http://localhost:3000/auth/callback - Express / FastAPI / Go:
http://localhost:3000/auth/callback
- Next.js:
- Click Create application, then copy the client ID into
.env(and the client secret, shown once on the page you land on, for confidential-client backends). - Next.js only: on the application's Configuration tab, add
http://localhost:3000under Browser CORS origins and click Save configuration.

The Quickstarts page in the portal shows the same values pre-filled, together with a ready-to-run lumo init command for the selected client.
Or do it from the CLI:
lumo apps create \
--name "My App (dev)" \
--redirect-uris http://localhost:3000/auth/callback \
--type web \
-o json
Combining with lumo dev
For a fully self-contained PR / branch environment:
# Spawn the sandbox and capture its slug (`-o json` prints the server's
# {"data": {...}} response on stdout)
SLUG=$(lumo dev start --name pr-1234 -o json | jq -r '.data.slug')
lumo init --framework next --dir ./web-pr-1234 --org "$SLUG"
cd ./web-pr-1234 && npm install && npm run dev
When the PR is done, lumo dev stop "$SLUG" and rm -rf ./web-pr-1234 and you're done.