I asked Claude to add auth to a Next.js app. Here's the exact prompt, and exactly what happened.
We've been previewing a new way to add Zitadel to your app: a CLI built to be driven by a coding agent, not just a developer typing commands. So I tried it the way we designed it to be tried — I handed an agent one prompt and a four-line script, and told it to take the result all the way through a real browser proof: register, sign out, sign back in.
Here's the prompt. Paste it into Claude Code, Cursor, or whatever you're using, in an empty directory:
Create or use an empty directory for a Next.js app. Use Node.js 24 or newer.
Install and run Zitadel through the CLI, not through a dashboard. Prefer
non-interactive JSON commands.
Run:
npx @zitadel/cli@alpha doctor --non-interactive --json
npx @zitadel/cli@alpha start --non-interactive --json
npx @zitadel/cli@alpha setup --framework next --server local --non-interactive --json
npm run dev
Then open http://localhost:3000/login in a browser. Register a user, verify
the signed-in state, log out, log back in with the same user, and finish on
the signed-in profile page.
Summarize what worked, what failed, which files changed, and any friction
you hit.
What follows is what actually happened — not a cleaned-up version.
What the agent did, in order
doctor, start, and setup all ran non-interactively, exactly as asked. No dashboard, no manual step in between.
doctorpassed every check: server binary present, state directory writable, port 8080 free, no leftover runtime state.startlaunched the local Zitadel server — binary backend, its own PID, logs written to.zitadel/local/server.log.setup --framework next --server localauto-detected the Next.js project, rannpm install, and scaffolded/login,/register,/profilepages, plusproxy.ts,zitadel.json,.env.local, and.env.example.npm run devstarted cleanly on port 3000 with Turbopack: "Ready in 124ms."
Then it actually finished the job
This is the part I was most curious about. The login component only runs in a real browser, so the agent needed browser tooling to complete the last step itself. The recommended chromium-cli wasn't available in its environment, so it installed Playwright as a dev dependency, downloaded Chromium, and drove the whole flow itself with a script:
- Registered a new user — email, given name, family name, date of birth, password.
- Landed on
/profile, which showed "Signed in profile loaded," an active session, and a user ID. - Opened the user menu and clicked sign out.
- Got redirected to
/login. - Logged back in with the same email and password.
- Landed on
/profileagain, same user ID — confirming the session was the same user, not a new one.
Server logs showed clean 200/201/204 responses the entire way through. No errors.
The one real friction point
Signing out wasn't a single click, and the first attempt silently failed.
<zitadel-logout> renders a button that opens a dropdown — clicking it doesn't sign you out, it just opens a menu. The actual sign-out action is a second button inside that dropdown, living in the component's shadow DOM. The agent's first attempt clicked only the visible trigger, got no error, and just... stayed on /profile. It had to inspect the shadow DOM to find the real sign-out control before the flow could continue.
This is a small thing, but it's exactly the kind of friction that matters: not "it crashed," but "it did nothing and gave no signal that anything was wrong." A two-step control with a silent no-op on the wrong click is worth fixing before this leaves preview.
What this actually proves
The whole loop — empty directory to a verified, two-cycle login session — completed with no human in it at any point. The agent didn't just run commands and report a JSON success message; it drove a real browser, hit a real bug, diagnosed it by inspecting the rendered DOM, and adapted its own approach (swapping in Playwright when the recommended tool wasn't available) without being told how.
That's the actual bar for "built for agents": not that the happy path works, but that an agent can recover when something in the middle doesn't.
Try it yourself
Run the prompt above in Claude Code or Cursor, or run the four commands yourself:
mkdir myapp && cd myapp
npx @zitadel/cli@alpha doctor
npx @zitadel/cli@alpha start
npx @zitadel/cli@alpha setup --framework next --server local
npm run dev
Then open http://localhost:3000/login and run the same loop: register, sign out, sign back in. If you hit the same logout dropdown — you'll know what's going on.
This is a local-only preview today — nothing persists across machines yet, and there's no Zitadel Cloud connection. If you want to know when that changes, join the waitlist or tell us what happened when you tried it in the GitHub Discussion.
If you hit a port conflict: the default port is 8080. If something else on your machine is already using it, doctor catches it before anything is provisioned and tells you exactly what to do:
Error E_PORT_IN_USE: Port 8080 is already in use.
Run `npx @zitadel/cli@alpha stop --all` for CLI-managed local runtimes,
then rerun doctor, or choose another port with `doctor --port 8081`.
That's the full recovery path — no further digging required.
