FAQ
Frequently asked questions about kreogen.
Why not tRPC?
Server Actions give similar type safety with tighter framework integration and less machinery. Being part of the framework, they also get optimised by the Next.js team rather than by an adapter chasing them.
Why was X chosen over Y?
The defaults are the tools Kreotic actually runs in client projects, weighted toward two things: they can be self-hosted, and they degrade cleanly when unconfigured. That rules out otherwise-excellent tools whose free tier is a trial or whose SDK throws without an API key.
They are not permanent. If a better option appears, open an issue — the argument to make is about self-hostability, operational cost and how it fails, not popularity.
Why is authentication self-hosted rather than a hosted provider?
Hosted authentication is genuinely faster to start with. It also means per-seat pricing on every client project, vendor branding in the sign-in flow that never quite matches the design system, and an outage you cannot do anything about.
Better Auth runs against the same Postgres as everything else, so there is one fewer account per project and the sign-in screens are ordinary components you can edit.
Why does the template ship a Content Security Policy that is actually on?
Because a policy that ships disabled is a policy nobody enables. It is enforced in production and report-only in development, so a missing directive surfaces as a console warning while you are working rather than as a broken page after deploying.
When you add an integration that talks to a new origin, extend the directives
in packages/security/proxy.ts.
Why is there a suppressHydrationWarning on every html tag?
It is what next-themes recommends, to suppress the warning that comes from
resolving the theme on the client.
Why are some folders excluded from linting?
Two kinds of file:
- Vendored shadcn/ui components. They come from the registry with their own conventions, and are meant to be regenerated. Formatting them locally would produce a diff on every update.
- Generated output — the Prisma client and the CMS type definitions.
Everything else is linted, including tests and configuration.
Why do integrations return undefined instead of throwing?
So that a project runs before every account exists. A missing key disables its
feature rather than breaking the boot, which means bun run dev works
immediately after init and you add services when you actually need them.
The two exceptions are DATABASE_URL and BETTER_AUTH_SECRET: without those
there is no application to run, so they fail loudly and immediately.
How do I get changes from the template into an existing project?
npx @kreotic/kreogen@latest updateIt diffs two template versions and applies the difference. It refuses to run
against a dirty working tree, so the result is always reviewable as a git
diff, and --dry-run shows what would change first.