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 filesApp 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.tsxAccount 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.tsxOrganization 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.tsxAdmin 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.tsxAPI Routes
app/api/
└── auth/
└── [...all]/
└── route.ts # Better Auth API handlerOther 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.tsxActions Directory (/actions)
Server actions for server-side operations.
actions/
└── update-profile-picture.tsServer 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.tsxOrganization 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.tsxUI 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.tsxOther Components
components/
├── faq.tsx
└── user-dropdown.tsxConfig Directory (/config)
Application configuration files.
config/
├── fonts.ts # Font configuration
└── site.ts # Site metadata and constantsEmails 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.tsxReact 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 utilitiesConvex
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 utilitiesPlugins
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.tsHooks
lib/hooks/
├── use-debounced-save.ts # Debounced autosave
├── use-loading-callback.ts # Loading state management
└── use-mobile.ts # Mobile detectionUtilities
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 notificationsSchemas Directory (/schemas)
Zod validation schemas.
schemas/
└── auth.ts # Auth form validation schemasScripts 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 visualizationStyles Directory (/styles)
Global CSS and Tailwind styles.
styles/
└── globals.css # Global styles and TailwindTypes Directory (/types)
TypeScript type definitions.
types/
└── organization.ts # Organization-related typesConfiguration 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 infonext.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.tsxUnderscore 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
- Create folder in
/app - Add
page.tsx - Add
layout.tsxif needed - Create
_componentsfor route-specific components
New Component
- Add to appropriate
/componentssubfolder - Export from component file
- Import where needed
- Keep reusable, not route-specific
New Action
- Create file in
/actions - Mark with
'use server' - Export async function
- Use from components
New Email Template
- Create in
/emails - Use React Email components
- Add to email sending logic
- Test in development
Best Practices
- Co-location: Keep related code together
- Separation: Separate UI from logic
- Reusability: Extract reusable components
- Type Safety: Use TypeScript everywhere
- Server Components: Default to server, client when needed
- Actions: Use server actions for mutations
- Validation: Validate all inputs with Zod
- Error Handling: Handle errors gracefully
Development Tips
- Use
_componentsfor 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