Unstack Pro Docs

FAQ

Frequently asked questions about Unstack Pro

Common questions and answers about Unstack Pro.

Unstack Pro ships in two editions that differ in where the data lives and where Better Auth runs. Answers that depend on which one you have are behind the switcher below — the choice is remembered across every page in these docs.

Better Auth runs inside Next.js and talks to PostgreSQL through Drizzle ORM. One environment surface, one process, SQL migrations.

Better Auth runs inside Convex. Two environment surfaces, two processes, and schema pushed rather than migrated.

General

What is Unstack Pro?

Unstack Pro is a production-ready Next.js template with authentication, organizations, and admin panel fully configured. It's designed to save you 100-200+ hours of development time by providing all the foundational features a SaaS application needs.

Who is Unstack Pro for?

  • Indie hackers building their first SaaS
  • Startups that need to ship fast
  • Developers who want to focus on product, not auth
  • Teams building B2B applications with organization support
  • Anyone who doesn't want to build auth from scratch

What tech stack does it use?

Everything except the data layer is shared:

TechnologyPurpose
Next.js 16React framework with App Router
React 19UI library
Tailwind CSSStyling
Shadcn/uiUI components
React Email + ResendTransactional emails
AutumnBilling
BiomeLinting and formatting
TypeScriptType safety
TechnologyPurpose
PostgreSQLDatabase
Drizzle ORMSchema, queries and migrations
pg (node-postgres)Database driver — no vendor lock-in
Better AuthAuthentication, running inside Next.js
TechnologyPurpose
ConvexReal-time database and backend
Better AuthAuthentication, running inside Convex via kitcn

Is it open source?

Unstack Pro is a premium template. You purchase a license to access the private repository, and then you own the code to use in your projects.

Can I use it for multiple projects?

Check your license terms. Typically, you can use the template for multiple personal or client projects, but cannot redistribute it.

Setup

How long does setup take?

Most developers are up and running in 10-15 minutes. The auth system is already configured - you just need to:

  1. Clone the repository
  2. Install dependencies
  3. Create a PostgreSQL database and a Resend account
  4. Configure .env.local
  5. Apply the migrations with bun run db:migrate
  6. Run the development server
  1. Clone the repository
  2. Install dependencies
  3. Set up Convex and Resend accounts
  4. Configure environment variables in .env.local and on the Convex deployment
  5. Run the development server alongside bun convex dev

Do I need to know the data layer?

Some familiarity helps once you start adding your own features — the auth side is already built either way.

You'll want working knowledge of SQL and Drizzle ORM. Your tables go in lib/db/schema.ts, reads live in Server Components via lib/server/*, and writes are server actions in actions/*. Schema changes are generated and applied with drizzle-kit.

You'll want basic Convex knowledge — how to write queries and mutations, and how indexes work. The Convex documentation is excellent for the basics. Your tables go in convex/schema.ts and your functions in convex/.

Do I need to know Better Auth?

No. Authentication is already configured. You only need to understand Better Auth if you want to customize auth flows.

What accounts do I need?

ServiceRequiredPurpose
A PostgreSQL databaseYesData storage — any provider
ResendYesEmail sending
AutumnOptionalBilling (can be removed)
VercelRecommendedDeployment
SentryOptionalError monitoring
ServiceRequiredPurpose
ConvexYesDatabase and backend
ResendYesEmail sending
AutumnOptionalBilling (can be removed)
VercelRecommendedDeployment
SentryOptionalError monitoring

Can I use a different database?

Any PostgreSQL will do. The app connects with pg (node-postgres), not a vendor-specific driver, so Neon and Supabase are convenient suggestions rather than requirements — a Postgres you run yourself works the same. Moving to a different engine would mean swapping the Drizzle dialect and regenerating every migration.

This edition is built specifically for Convex and relies on its real-time features, so switching databases would require significant modifications. If you want SQL, use the Postgres edition instead.

Can I use a different email provider?

Yes, but you'd need to modify the email sending code. Resend + React Email is the recommended and pre-configured option.

Authentication

What authentication methods are supported?

  • Email/password with verification
  • OTP (one-time password) via email
  • Passkeys (WebAuthn) for passwordless auth
  • Two-factor authentication (TOTP)
  • OAuth providers (can be added)

Is email verification required?

Yes. Users must verify their email address before they can sign in. This ensures valid email addresses and improves security.

Can I disable email verification?

You could modify the Better Auth configuration, but it's not recommended. Email verification is a security best practice.

Can I add social login (Google, GitHub, etc.)?

Yes! Better Auth supports many OAuth providers. See the Customization Guide for instructions.

How do passkeys work?

Passkeys use biometric authentication (Face ID, Touch ID, Windows Hello) or security keys. Users register a passkey from their account settings and can then sign in without a password.

Requirements:

  • HTTPS in production (localhost works for development)
  • Modern browser with WebAuthn support
  • PASSKEY_RP_ID must match your domain

How does 2FA work?

Users can enable two-factor authentication from their security settings:

  1. Enable 2FA (requires password confirmation)
  2. Scan QR code with authenticator app
  3. Verify with a code
  4. Save 12 backup codes for recovery

When signing in with 2FA enabled, users enter their email/password, then are prompted for a TOTP code.

What happens if a user loses access to their 2FA?

Users can use one of their 12 backup codes to sign in. Each backup code works once. If they've used all backup codes, they'll need admin assistance to disable 2FA on their account.

Organizations

What is the organization system?

Organizations provide multi-tenant support for B2B applications. Each organization:

  • Has its own members
  • Has roles and permissions
  • Can have teams
  • Has its own billing (via Autumn)

What roles are available?

Default roles:

RolePermissions
OwnerFull control, can delete organization
AdminManage members and settings
MemberBasic access and collaboration

You can also create custom roles with specific permissions.

Can users belong to multiple organizations?

Yes. Users can be members of multiple organizations and switch between them.

How does organization billing work?

Organizations use per-seat pricing through Autumn. Each member added to an organization counts as a seat. Organizations must be on the Pro plan to add members beyond the owner.

Can I remove organization billing?

Yes. See the Billing documentation for instructions on removing Autumn integration.

Admin Panel

Who can access the admin panel?

Only users with the admin role can access /admin.

How do I create the first admin?

Register a normal account first, then promote it by hand — there is no bootstrap flow, and no environment variable that grants the role.

Set the role column on your row in the user table, then refresh your browser:

update "user" set role = 'admin' where email = 'you@example.com';

Open the Convex dashboard, go to the user table in the data browser, edit your row's role field to admin, then refresh your browser.

What can admins do?

  • View all users
  • Create users
  • Change user passwords
  • Verify emails manually
  • Set user roles
  • Ban/unban users
  • Revoke user sessions
  • Impersonate users (for support)

Are admin actions logged?

Admin actions are not currently audited. The audit system tracks user authentication and account events, but not admin panel activities.

Can I impersonate any user?

Admins can impersonate regular users but cannot impersonate other admins (safety feature).

Billing

Is Autumn required?

Autumn is required for organization billing features. If you don't need billing, you can remove Autumn entirely.

How does per-seat pricing work?

Each organization member counts as a seat. When you add a member, the seat count increases and billing adjusts automatically. When you remove a member, the seat count decreases.

Can I use Stripe instead?

Unstack Pro is configured for Autumn. Using Stripe would require replacing the billing integration code.

What happens if payment fails?

The organization owner is notified. Depending on your Autumn configuration, the subscription may enter a grace period or be canceled.

Deployment

Where can I deploy?

Vercel is recommended and documented. Other platforms that support Next.js should also work:

  • Vercel (recommended)
  • Netlify
  • Railway
  • Self-hosted

Do I need separate environments for dev and production?

Yes, and never point production at your development data.

Two databases: your local DATABASE_URL and a separate production one. There is no second deployment environment to manage — Better Auth runs inside Next.js, so the only thing that changes between environments is the set of variables your host provides.

Two Convex deployments — a development one and a production one — each with its own environment variables. bun convex dev targets the former; bunx convex deploy and --prod target the latter.

How do I handle environment variables in production?

One surface: your hosting platform's dashboard (for example Vercel Environment Variables). Everything the app reads — DATABASE_URL, BETTER_AUTH_SECRET, RESEND_API_KEY and the rest — lives there.

Two surfaces: your hosting platform's dashboard for the Next.js side, and the Convex production deployment for everything Better Auth reads, set with bunx convex env set NAME "value" --prod.

Do I need HTTPS?

For production, yes. HTTPS is required for:

  • Passkey authentication
  • Secure cookies
  • OAuth callbacks
  • General security

Customization

Can I change the UI/branding?

Yes. Customize:

  • Colors in styles/globals.css
  • Logo and favicon in public/
  • Site metadata in config/site.ts
  • Fonts in config/fonts.ts

Can I add my own features?

Absolutely. Routes go in app/ and components in components/, in both editions. Where the data side goes depends on yours:

  • Database tables in lib/db/schema.ts, applied with bun run db:generate and bun run db:migrate
  • Reads in lib/server/, called from Server Components
  • Writes as server actions in actions/
  • Database tables in convex/schema.ts
  • Queries, mutations and actions in convex/

Can I modify the auth flow?

Yes, but be careful. The auth system is complex and interconnected. Test thoroughly after any changes.

Can I remove features I don't need?

Yes. Common removals:

  • Billing (Autumn)
  • Error monitoring (Sentry)
  • Passkeys
  • Teams
  • Custom roles

See Customization Guide.

Security

Is the template secure?

Yes. Unstack Pro implements security best practices:

  • Password hashing (bcrypt)
  • HIBP password breach detection
  • Secure session management
  • CSRF protection
  • httpOnly cookies
  • Email verification
  • 2FA support
  • Audit logging

Is data encrypted?

  • Passwords are hashed (not stored in plain text)
  • TOTP secrets are encrypted
  • Sessions use secure tokens

Encryption at rest is a property of where the data lives:

Your database provider's responsibility. Most managed Postgres services encrypt at rest by default; check yours, and use sslmode=require so the connection is encrypted in transit too.

Convex encrypts data at rest for you.

How are sessions managed?

Sessions are managed by Better Auth with httpOnly cookies. Sessions can be viewed and revoked from account settings or by admins.

Is there rate limiting?

Basic rate limiting is in place. For production, consider adding additional rate limiting with Upstash Redis or similar.

Troubleshooting

Auth isn't working

Most common causes:

  1. NEXT_PUBLIC_APP_URL doesn't match the URL you're actually on
  2. Cookies blocked by the browser, or missing HTTPS in production
  3. BETTER_AUTH_SECRET changed, invalidating every existing session
  1. DATABASE_URL is unset or unreachable
  2. Pending migrations in drizzle/ were never applied, so an auth table or column the code expects doesn't exist
  1. Convex isn't running (bun convex dev)
  2. BETTER_AUTH_SECRET or JWKS is missing on the Convex deployment, or JWKS was not regenerated after BETTER_AUTH_SECRET changed

Emails aren't sending

Check:

  1. RESEND_API_KEY is correct
  2. EMAIL_FROM uses a verified domain
  3. In test mode, recipient must be verified
  4. Check Resend dashboard for errors

Database connection fails

Verify:

  1. DATABASE_URL is set in .env.local and reachable from where you're running
  2. The connection string carries ?sslmode=require if your provider needs it
  3. The provider's connection limit isn't exhausted

Verify:

  1. Convex is running (bun convex dev)
  2. CONVEX_DEPLOYMENT, NEXT_PUBLIC_CONVEX_URL and NEXT_PUBLIC_CONVEX_SITE_URL all name the same deployment
  3. The deployment exists in the Convex dashboard

See the full Troubleshooting Guide for more solutions.

Support

Where can I get help?

  1. Check this documentation
  2. Review the Troubleshooting Guide
  3. Search the codebase for examples
  4. Check library documentation:

Can I request features?

Feature requests can be submitted through the appropriate channels provided with your purchase.

How do I report bugs?

Report bugs with:

  1. Steps to reproduce
  2. Expected behavior
  3. Actual behavior
  4. Error messages
  5. Environment details

Updates

Will I get updates?

Yes. On purchase you're invited to the template repository, so your own git credentials can fetch it. You pull ongoing fixes and features into your project with a single command.

The Postgres-edition template repository is not published yet; the Convex edition is the one distributed today.

The repository is unstack-pro/nextjs-convex.

How do I update?

Run the template-sync script from your repo root:

bun scripts/sync-template.ts

It fetches the template, previews the changelog, creates a sync branch, merges, then pushes and opens a pull request against your default branch. See the full Template Updates guide for flags (--check-only, --no-pr, --auto-merge) and conflict resolution. Review the changelog in the PR for any breaking changes before merging.

Will updates break my customizations?

Updates are designed to be non-breaking when possible. Keep your customizations separate from core files to make updates easier.

Still have questions? Check the documentation sections for more detailed information on specific topics.

On this page

GeneralWhat is Unstack Pro?Who is Unstack Pro for?What tech stack does it use?Is it open source?Can I use it for multiple projects?SetupHow long does setup take?Do I need to know the data layer?Do I need to know Better Auth?What accounts do I need?Can I use a different database?Can I use a different email provider?AuthenticationWhat authentication methods are supported?Is email verification required?Can I disable email verification?Can I add social login (Google, GitHub, etc.)?How do passkeys work?How does 2FA work?What happens if a user loses access to their 2FA?OrganizationsWhat is the organization system?What roles are available?Can users belong to multiple organizations?How does organization billing work?Can I remove organization billing?Admin PanelWho can access the admin panel?How do I create the first admin?What can admins do?Are admin actions logged?Can I impersonate any user?BillingIs Autumn required?How does per-seat pricing work?Can I use Stripe instead?What happens if payment fails?DeploymentWhere can I deploy?Do I need separate environments for dev and production?How do I handle environment variables in production?Do I need HTTPS?CustomizationCan I change the UI/branding?Can I add my own features?Can I modify the auth flow?Can I remove features I don't need?SecurityIs the template secure?Is data encrypted?How are sessions managed?Is there rate limiting?TroubleshootingAuth isn't workingEmails aren't sendingDatabase connection failsSupportWhere can I get help?Can I request features?How do I report bugs?UpdatesWill I get updates?How do I update?Will updates break my customizations?