Quickback Docs

Feature Flags

Enable and configure Account UI features

Feature Flags

Control which features are available in your Account UI deployment using feature flags. All flags are boolean environment variables and all of them carry the VITE_ prefix — Vite only exposes VITE_* vars to client code, so an unprefixed ENABLE_PASSKEY=true is silently ignored.

Where these come from

Resolution order for every flag is: worker-injected window.__QUICKBACK_RUNTIME blob → baked VITE_* env → built-in default. When a Quickback worker serves the Account UI it injects your quickback.config.ts account.auth settings into the blob, so you normally set these in the config rather than in a .env file. See With Quickback.

Reference

appConfig.features

These ten flags populate appConfig.features and are the ones isFeatureEnabled() accepts.

Variablefeatures keyDefault
VITE_ENABLE_ORGANIZATIONSorganizationsfalse
VITE_ENABLE_ORG_TEAMSorgTeamsfalse
VITE_ENABLE_ADMINadmintrue
VITE_ENABLE_FILE_UPLOADSfileUploadsfalse
VITE_ENABLE_PASSKEYpasskeyfalse
VITE_ENABLE_EMAIL_OTPemailOTPfalse
VITE_ENABLE_PASSWORDpasswordtrue
VITE_ENABLE_GOOGLE_OAUTHgoogleOAuthfalse
VITE_ENABLE_SUBSCRIPTIONSsubscriptionsfalse
VITE_ENABLE_REALTIMErealtimefalse

appConfig.auth

Three further flags configure the signup and email flows. They live on appConfig.auth, not on appConfig.featuresisFeatureEnabled() does not accept them.

Variableauth keyDefault
VITE_ENABLE_SIGNUPenableSignuptrue
VITE_ENABLE_EMAIL_VERIFICATIONrequireEmailVerificationtrue
VITE_DISABLE_EMAIL_STATUS_CHECKdisableEmailStatusCheckfalse

Password is on, passkey and OTP are off

The out-of-the-box posture is email + password only. Passkey, email OTP, organizations, and Google OAuth all default to false — you opt in. Admin defaults to true.

These are the SPA's built-in defaults — the compiler overrides most of them

The defaults above are what the Account SPA falls back to when nothing else sets a flag. In a compiled Quickback project the compiler derives the flags from your Better Auth config and account.auth shorthand, and only emits a VITE_* value when it has one — an unset flag emits nothing and the built-in default applies.

Two derivations are worth knowing because they do not match the built-in default:

  • organizations resolves to true unless you set account.auth.organizations: false, so a compiled project has organizations on even though the SPA default is false.
  • admin is emitted only when you set account.auth.admin. Leave it unset and the compiler strips the /admin route files from the bundle while the SPA's built-in admin: true default still reports the feature as enabled. Set account.auth.admin explicitly — in either direction — rather than relying on the default.

Authentication Features

User Signup

VITE_ENABLE_SIGNUP=true  # default: true

Controls whether new users can register.

When enabled:

  • Shows "Sign Up" link on login page
  • /signup route is accessible
  • New users can create accounts

When disabled:

  • Signup route returns 404
  • Only existing users can log in
  • Useful for invite-only applications

Email Verification

VITE_ENABLE_EMAIL_VERIFICATION=true  # default: true

Controls the email verification flow.

When enabled:

  • Users must verify email before full access
  • Verification email sent on signup
  • "Resend verification email" option available
  • Unverified users see verification prompt

When disabled:

  • Email addresses are trusted without verification
  • Users have immediate access after signup

Security Consideration

Disabling email verification can allow fake email addresses. Only disable if you have another verification mechanism.

Email Deliverability Check

VITE_DISABLE_EMAIL_STATUS_CHECK=false  # default: false

Note the inverted sense — this flag disables a check that is on by default.

When false (checking enabled):

  • System validates email addresses are deliverable
  • Rejects disposable/temporary email providers
  • Prevents typos in domain names

When true (checking disabled):

  • Accepts all email formats
  • Useful for development/testing
  • Allows @test.com, @localhost, etc.

Password Authentication

VITE_ENABLE_PASSWORD=true  # default: true

When enabled:

  • Email + password fields on login page
  • Password field on signup page
  • Traditional username/password authentication

When disabled:

  • No password fields shown
  • Users authenticate via email OTP or passkey

Passkey Login

VITE_ENABLE_PASSKEY=false  # default: false

Controls passkey LOGIN only (not signup). When enabled, users can authenticate using passkeys.

When enabled:

  • Users can register passkeys (fingerprint, Face ID, hardware keys)
  • Passwordless login option
  • "Manage Passkeys" page available

When disabled:

  • No passkey registration
  • No passkey login option

Requirements:

  • HTTPS (passkeys require secure context)
  • Modern browser with WebAuthn support

Email OTP

VITE_ENABLE_EMAIL_OTP=false  # default: false

When enabled:

  • Users can receive one-time passwords via email
  • Alternative to password login
  • /email-otp route available

When disabled:

  • No email OTP option
  • Password or passkey required

Google OAuth

VITE_ENABLE_GOOGLE_OAUTH=false  # default: false

When enabled:

  • "Continue with Google" button on the login and signup pages
  • Google row in the profile page's Connected Accounts card

When disabled:

  • No social sign-in button, no Connected Accounts row

Requirements:

  • Google OAuth credentials configured on the Better Auth side

Account Management Features

File Uploads

VITE_ENABLE_FILE_UPLOADS=false  # default: false

When enabled:

  • Avatar/profile picture upload
  • Image cropping and editing
  • File upload to R2/S3

When disabled:

  • No file upload functionality
  • Users can only use default avatars

Requirements:

  • R2 bucket or S3 configured
  • Upload endpoints in your API

Subscriptions

VITE_ENABLE_SUBSCRIPTIONS=false  # default: false

When enabled:

  • Subscription card on the organization page
  • Subscription management in the admin dashboard

When disabled:

  • No billing surface in the Account UI

Realtime

VITE_ENABLE_REALTIME=false  # default: false

When enabled:

  • The Account SPA opens a realtime websocket connection and reacts to server broadcasts (including the best-effort auth:token-invalidated event described in JWT Optimization)

When disabled:

  • No websocket connection

Organization Features

Organizations (Multi-Tenancy)

VITE_ENABLE_ORGANIZATIONS=false  # default: false

When enabled:

  • Users can create organizations
  • Organization management pages
  • Member invitations and roles
  • /organizations/* routes

When disabled:

  • Single-user mode only
  • No organization features
  • Simpler user experience

Includes:

  • Organization creation and deletion
  • Member management (owner, admin, member roles)
  • Invitation system
  • Organization settings

Teams

VITE_ENABLE_ORG_TEAMS=false  # default: false

Sub-groups within an organization. Auto-set to true by the compiler when your Better Auth config has organization({ teams: { enabled: true } }). When false, the Teams tab is hidden and the auth client does not expose team APIs.

Admin Features

Admin Panel

VITE_ENABLE_ADMIN=true  # default: true

When enabled:

  • /admin route accessible to admin users
  • User management dashboard
  • Subscription management
  • Admin-only features:
    • Create users manually
    • Ban/unban users
    • Reset user passwords
    • View all sessions
    • Manage subscriptions

When disabled:

  • No admin panel
  • Admin must use database directly

Requirements:

  • User must have admin role in database

Feature Combinations

Minimal Configuration (Password-Only)

VITE_ENABLE_PASSWORD=true
VITE_ENABLE_PASSKEY=false
VITE_ENABLE_EMAIL_OTP=false
VITE_ENABLE_ORGANIZATIONS=false
VITE_ENABLE_ADMIN=false

Simple email/password authentication for apps that do not need advanced auth methods. Only VITE_ENABLE_ADMIN differs from the built-in defaults here.

Maximum Security

VITE_ENABLE_PASSKEY=true
VITE_ENABLE_EMAIL_OTP=true
VITE_ENABLE_PASSWORD=false
VITE_ENABLE_EMAIL_VERIFICATION=true

Passwordless authentication with email verification and deliverability checks.

Multi-Tenant SaaS

VITE_ENABLE_PASSKEY=true
VITE_ENABLE_EMAIL_OTP=true
VITE_ENABLE_ORGANIZATIONS=true
VITE_ENABLE_ORG_TEAMS=true
VITE_ENABLE_ADMIN=true

Full-featured SaaS with organizations, teams, and admin panel.

Invite-Only Platform

VITE_ENABLE_SIGNUP=false
VITE_ENABLE_PASSKEY=true
VITE_ENABLE_ORGANIZATIONS=true
VITE_ENABLE_ADMIN=true

No public signup — users must be created by admin or invited to organizations.

Feature Detection

Check if a feature is enabled in your code:

import { isFeatureEnabled } from '@/config/app';

if (isFeatureEnabled('organizations')) {
  // Show organizations menu
}

if (isFeatureEnabled('passkey')) {
  // Offer passkey setup
}

isFeatureEnabled() accepts only the ten appConfig.features keys listed above. The three appConfig.auth flags are read from appConfig.auth directly:

import { appConfig } from '@/config/app';

if (appConfig.auth.enableSignup) {
  // Show the sign-up link
}

Dynamic Feature Configuration

Override features at runtime:

import { setAppConfig } from '@/config/app';

setAppConfig({
  features: {
    organizations: false,  // Hide organization-management UI
    passkey: true,         // Enable passkey
  },
});

setAppConfig wins over the baked env

setAppConfig() merges its overrides into the already-resolved config, so it takes precedence over both the runtime blob and the baked VITE_* values. Use it for progressive feature rollouts or A/B testing. It cannot resurrect anything the build dropped: when organizations, passkey, or admin is off at compile time the compiler removes those route files before Vite runs, so re-enabling them at runtime shows a menu entry pointing at a route that is not in the bundle.

Testing Features

For local development, create .env.local:

.env.local
# Test with all features enabled
VITE_ENABLE_SIGNUP=true
VITE_ENABLE_EMAIL_VERIFICATION=true
VITE_ENABLE_PASSKEY=true
VITE_ENABLE_EMAIL_OTP=true
VITE_ENABLE_PASSWORD=true
VITE_ENABLE_ORGANIZATIONS=true
VITE_ENABLE_ADMIN=true
VITE_ENABLE_FILE_UPLOADS=true
VITE_DISABLE_EMAIL_STATUS_CHECK=true  # Allow test emails

Next Steps

On this page