Unstack Pro Docs

Project Structure

Understanding the Unstack Pro codebase organization

Project Structure

Understand the codebase so you can build your product on top. Auth, organizations, and admin are already organized and working.

You don't need to modify the auth system. Focus on the /app directory where you'll build your product features.

Root Structure

convex-better-auth/
├── app/                    # Next.js App Router pages
├── actions/                # Server actions
├── components/             # Reusable React components
├── config/                 # Configuration files
├── emails/                 # Email templates (React Email)
├── lib/                    # Utilities and core logic
├── schemas/                # Validation schemas (Zod)
├── scripts/                # Build and utility scripts
├── styles/                 # Global styles
├── types/                  # TypeScript type definitions
└── ... config files

App Directory (/app)

Next.js 15 App Router structure with all routes.

Authentication Routes

app/auth/
├── layout.tsx              # Auth pages layout
├── page.tsx                # Auth redirect/landing
├── login/
│   ├── page.tsx
│   ├── loading.tsx
│   ├── 2fa/
│   │   ├── page.tsx
│   │   ├── loading.tsx
│   │   └── _components/
│   │       ├── backup-code-verify-form.tsx
│   │       ├── totp-verify-form.tsx
│   │       └── two-factor-form.tsx
│   └── _components/
│       ├── login-form.tsx
│       ├── otp-request-form.tsx
│       ├── passkey-login-button.tsx
│       └── password-login-form.tsx
├── register/
│   ├── page.tsx
│   ├── loading.tsx
│   └── _components/
│       └── register-form.tsx
└── forgot-password/
    ├── page.tsx
    ├── loading.tsx
    └── _components/
        ├── email-request-form.tsx
        ├── forgot-password-form.tsx
        └── reset-password-form.tsx

Account Routes

app/account/
├── layout.tsx              # Account layout with sidebar
├── page.tsx                # Account dashboard
├── loading.tsx
├── settings/
│   ├── page.tsx
│   ├── loading.tsx
│   └── _components/
│       └── settings-client.tsx
├── security/
│   ├── page.tsx            # Security overview
│   ├── sessions/
│   │   ├── page.tsx
│   │   ├── loading.tsx
│   │   └── _components/
│   │       ├── revoke-all-sessions-button.tsx
│   │       ├── revoke-other-sessions-button.tsx
│   │       ├── revoke-session-button.tsx
│   │       ├── session-card.tsx
│   │       └── sessions-client.tsx
│   ├── two-factor/
│   │   ├── page.tsx
│   │   ├── loading.tsx
│   │   └── _components/
│   │       ├── backup-codes-step.tsx
│   │       ├── disable-two-factor.tsx
│   │       ├── enable-two-factor-form.tsx
│   │       ├── otp-verify-step.tsx
│   │       ├── qr-code-step.tsx
│   │       ├── regenerate-backup-codes.tsx
│   │       ├── two-factor-configure-form.tsx
│   │       ├── two-factor-status-card.tsx
│   │       └── view-backup-codes.tsx
│   ├── passkeys/
│   │   ├── page.tsx
│   │   ├── loading.tsx
│   │   └── _components/
│   │       ├── delete-passkey-dialog.tsx
│   │       ├── edit-passkey-name-dialog.tsx
│   │       ├── empty-state.tsx
│   │       ├── passkey-card.tsx
│   │       ├── passkeys-client-list.tsx
│   │       └── register-passkey-button.tsx
│   ├── audit/
│   │   ├── page.tsx
│   │   ├── loading.tsx
│   │   └── _components/
│   │       ├── audit-card.tsx
│   │       └── audit-client.tsx
│   └── _components/
│       ├── delete-account-dialog.tsx
│       ├── delete-confirmation-form.tsx
│       └── security-settings-client.tsx
├── connections/
│   ├── page.tsx
│   ├── loading.tsx
│   └── _components/
│       ├── connection-card.tsx
│       ├── connections-client.tsx
│       ├── empty-state.tsx
│       └── unlink-account-button.tsx
├── invitations/
│   ├── page.tsx
│   ├── loading.tsx
│   └── _components/
│       ├── invitation-highlighter.tsx
│       └── invitations-client.tsx
└── delete/
    ├── page.tsx
    ├── loading.tsx
    └── _components/
        └── delete-account-form.tsx

Organization Routes

app/organizations/
├── layout.tsx              # Org layout
├── page.tsx                # Org list
├── loading.tsx
└── [organizationSlug]/
    ├── page.tsx            # Org dashboard
    ├── loading.tsx
    ├── members/
    │   ├── page.tsx
    │   ├── loading.tsx
    │   └── _components/
    │       └── members-table.tsx
    ├── invitations/
    │   ├── page.tsx
    │   ├── loading.tsx
    │   └── _components/
    │       ├── accept-invitation-button.tsx
    │       ├── cancel-invitation-button.tsx
    │       ├── invitation-card.tsx
    │       ├── invitations-list.tsx
    │       └── reject-invitation-button.tsx
    ├── teams/
    │   ├── page.tsx
    │   ├── loading.tsx
    │   ├── [teamId]/
    │   │   ├── page.tsx
    │   │   └── loading.tsx
    │   └── _components/
    │       └── teams-list.tsx
    ├── roles/
    │   ├── page.tsx
    │   ├── loading.tsx
    │   └── _components/
    │       ├── create-role-dialog.tsx
    │       ├── edit-role-dialog.tsx
    │       ├── roles-manager.tsx
    │       └── roles-table.tsx
    ├── settings/
    │   ├── page.tsx
    │   ├── loading.tsx
    │   └── _components/
    │       ├── delete-organization-dialog.tsx
    │       ├── edit-organization-name.tsx
    │       ├── organization-image-uploader.tsx
    │       └── settings-client.tsx
    └── billing/
        ├── page.tsx
        ├── loading.tsx
        └── _components/
            ├── manage-billing.tsx
            ├── orders-table.tsx
            ├── plan-hero-card.tsx
            └── upgrade-plan-button.tsx

Admin Routes

app/admin/
├── page.tsx                # Admin dashboard
├── loading.tsx             # Loading state
└── _components/
    ├── admin-stats.tsx
    ├── ban-user-dialog.tsx
    ├── banned-users-table.tsx
    ├── change-password-dialog.tsx
    ├── create-user-dialog.tsx
    ├── revoke-sessions-dialog.tsx
    ├── set-role-dialog.tsx
    ├── users-manager.tsx
    ├── users-table.tsx
    └── verify-email-dialog.tsx

API Routes

app/api/
└── auth/
    └── [...all]/
        └── route.ts        # Better Auth API handler

Other Routes

app/
├── layout.tsx              # Root layout
├── page.tsx                # Home page
├── providers.tsx           # App providers
├── global-error.tsx        # Global error boundary
├── goodbye/
│   ├── page.tsx            # Account deleted confirmation
│   └── loading.tsx
└── success/
    ├── page.tsx            # Success page
    └── loading.tsx

Actions Directory (/actions)

Server actions for server-side operations.

actions/
└── update-profile-picture.ts

Server actions provide type-safe server-side functions callable from client components.

Components Directory (/components)

Reusable React components organized by category.

Auth Components

components/auth/
├── change-password-form.tsx
├── controlled-email-input.tsx
├── controlled-input.tsx
├── controlled-otp-input.tsx
├── controlled-password-input.tsx
├── editable-email-input.tsx
├── editable-name-input.tsx
├── form-submit-button.tsx
├── logout-button.tsx
├── otp-input.tsx
├── otp-verify-form.tsx
├── password-confirmation-form.tsx
├── password-input.tsx
├── profile-picture-uploader.tsx
├── profile-sidebar.tsx
├── resend-control.tsx
└── verify-email-dialog.tsx

Organization Components

components/organization/
├── add-member-card.tsx
├── add-member-form.tsx
├── add-member-to-team-dialog.tsx
├── create-organization-dialog.tsx
├── create-team-dialog.tsx
├── invite-member-dialog.tsx
├── member-card.tsx
├── organization-selector.tsx
├── organization-sidebar.tsx
├── role-multiselect.tsx
├── team-card.tsx
├── team-members-empty-state.tsx
└── teams-empty-state.tsx

UI Components

components/ui/
├── button.tsx
├── card.tsx
├── command.tsx
├── dialog.tsx
├── dropdown-menu.tsx
├── input.tsx
├── multi-select.tsx
├── popover.tsx
├── select.tsx
├── separator.tsx
├── sheet.tsx
├── sidebar.tsx
├── skeleton.tsx
├── table.tsx
├── tooltip.tsx
└── visually-hidden.tsx

Other Components

components/
├── faq.tsx
└── user-dropdown.tsx

Config Directory (/config)

Application configuration files.

config/
├── fonts.ts                # Font configuration
└── site.ts                 # Site metadata and constants

Emails Directory (/emails)

React Email templates for transactional emails.

emails/
├── delete-account-verification.tsx
├── email-change-verification.tsx
├── organization-invitation-email.tsx
├── reset-password-email.tsx
├── signin-otp-email.tsx
└── verification-email.tsx

React Email lets you write email templates in React with great previews.

Lib Directory (/lib)

Core application logic and utilities.

Authentication

lib/
├── auth-client.ts          # Better Auth client config
├── auth-helpers.ts         # Auth utility functions
├── auth-server.ts          # Better Auth server config
├── autumn.ts               # Autumn SDK integration
├── http-polyfills.ts       # HTTP polyfills
├── permissions.ts          # RBAC permissions
├── session.ts              # Session management
└── utils.ts                # General utilities

Convex

lib/convex/
├── convex-provider.tsx     # Convex React provider
├── query-client.tsx        # Query client setup
├── rsc.tsx                 # React Server Components helpers
└── server.ts               # Server-side Convex utilities

Plugins

lib/plugin/
├── audit/                  # Audit logging plugin
│   ├── client.ts
│   ├── index.ts
│   └── server.ts
├── overrides/              # Custom auth overrides
│   ├── client.ts
│   ├── index.ts
│   └── server.ts
└── reverify/               # Re-verification plugin
    ├── client.ts
    ├── index.ts
    └── server.ts

Hooks

lib/hooks/
├── use-debounced-save.ts   # Debounced autosave
├── use-loading-callback.ts # Loading state management
└── use-mobile.ts           # Mobile detection

Utilities

lib/utils/
├── admin.ts                # Admin-related utilities
├── currency.ts             # Currency formatting
├── date.ts                 # Date formatting
├── download.ts             # File download utilities
├── organization.ts         # Org management utilities
├── string.ts               # String utilities
└── toast.ts                # Toast notifications

Schemas Directory (/schemas)

Zod validation schemas.

schemas/
└── auth.ts                 # Auth form validation schemas

Scripts Directory (/scripts)

Build and utility scripts.

scripts/
├── compile-all-pages.ts    # Page compilation script
├── line-count.ts           # Line counting utility
└── view-file-tree.ts       # File tree visualization

Styles Directory (/styles)

Global CSS and Tailwind styles.

styles/
└── globals.css             # Global styles and Tailwind

Types Directory (/types)

TypeScript type definitions.

types/
└── organization.ts         # Organization-related types

Configuration Files

Root Config Files

├── .env                    # Environment variables
├── .env.example            # Example environment template
├── .env.local              # Local environment overrides
├── .env.sentry-build-plugin # Sentry build configuration
├── .gitignore              # Git ignore rules
├── @useautumn-sdk.d.ts     # Autumn SDK type definitions
├── autumn.config.ts        # Autumn configuration
├── biome.json              # Biome linting/formatting
├── components.json         # Shadcn/ui configuration
├── instrumentation-client.ts # Client-side instrumentation
├── instrumentation.ts      # Server instrumentation
├── next-env.d.ts           # Next.js TypeScript env
├── next.config.js          # Next.js configuration
├── package.json            # Dependencies and scripts
├── postcss.config.js       # PostCSS configuration
├── sentry.edge.config.ts   # Sentry Edge Runtime config
├── sentry.server.config.ts # Sentry server config
├── tailwind.config.js      # Tailwind CSS configuration
├── tsconfig.json           # TypeScript configuration
└── tsconfig.tsbuildinfo    # TypeScript build info

next.config.js

Next.js configuration with Sentry integration.

instrumentation.ts & instrumentation-client.ts

Sentry instrumentation for error tracking.

sentry.edge.config.ts

Sentry configuration for Edge Runtime functions.

sentry.server.config.ts

Sentry configuration for server-side error tracking.

tailwind.config.js

Tailwind CSS configuration with custom theme.

tsconfig.json

TypeScript configuration with path aliases.

Important aliases:

{
  "@/*": "./*"              # Root import alias
}

biome.json

Biome configuration for linting and formatting.

package.json

Dependencies and scripts:

{
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "biome lint",
    "format": "biome format"
  }
}

File Conventions

Loading States

loading.tsx files provide loading UI:

// app/admin/loading.tsx
export default function Loading() {
  return <Skeleton />
}

Error Boundaries

error.tsx and global-error.tsx files handle errors:

// app/global-error.tsx
export default function GlobalError({ error, reset }) {
  return <ErrorUI error={error} retry={reset} />
}

Layouts

layout.tsx files wrap route segments:

// app/account/layout.tsx
export default function AccountLayout({ children }) {
  return (
    <div>
      <Sidebar />
      {children}
    </div>
  )
}

Component Organization

Pattern: _components folders for route-specific components:

app/admin/
├── page.tsx
└── _components/            # Admin-only components
    ├── users-table.tsx
    └── admin-stats.tsx

Underscore prefixed folders are not treated as routes by Next.js.

Key Technologies

Frontend

  • Next.js 15: App Router, Server Components
  • React 19: Latest React features
  • Tailwind CSS: Utility-first styling
  • Shadcn/ui: Component library
  • React Hook Form: Form handling
  • Zod: Schema validation

Backend

  • Better Auth: Authentication framework (via better-convex)
  • Convex: Realtime database
  • Resend: Email service
  • React Email: Email templates

Development

  • TypeScript: Type safety
  • Biome: Fast linting/formatting
  • Sentry: Error tracking (optional)

Adding New Features

New Route

  1. Create folder in /app
  2. Add page.tsx
  3. Add layout.tsx if needed
  4. Create _components for route-specific components

New Component

  1. Add to appropriate /components subfolder
  2. Export from component file
  3. Import where needed
  4. Keep reusable, not route-specific

New Action

  1. Create file in /actions
  2. Mark with 'use server'
  3. Export async function
  4. Use from components

New Email Template

  1. Create in /emails
  2. Use React Email components
  3. Add to email sending logic
  4. Test in development

Best Practices

  1. Co-location: Keep related code together
  2. Separation: Separate UI from logic
  3. Reusability: Extract reusable components
  4. Type Safety: Use TypeScript everywhere
  5. Server Components: Default to server, client when needed
  6. Actions: Use server actions for mutations
  7. Validation: Validate all inputs with Zod
  8. Error Handling: Handle errors gracefully

Development Tips

  • Use _components for route-specific components
  • Keep components/ for truly reusable components
  • Server Components are default, add 'use client' when needed
  • Use path alias @/ for clean imports
  • Follow existing patterns for consistency

On this page