Skip to content

Latest commit

 

History

History
86 lines (71 loc) · 6.15 KB

File metadata and controls

86 lines (71 loc) · 6.15 KB

AGENTS.md

This file provides guidance to coding agents when working with code in this repository.

Development Commands

Essential Commands

  • Install dependencies: pnpm install
  • Run tests: pnpm test run (uses Vitest). You can filter with pnpm test run <file-filters>. The run is important to not trigger watch mode
  • Lint code: pnpm lint. pnpm lint --fix will fix some of the linting errors, prefer that over fixing them manually.
  • Type check: pnpm typecheck

Extra commands

These commands are usually already called by the user, but you can remind them to run it for you if they forgot to.

  • Build packages: pnpm build:packages
  • Start dependencies: pnpm restart-deps (resets & restarts Docker containers for DB, Inbucket, etc. Usually already called by the user)
  • Run development: Already called by the user in the background. You don't need to do this. This will also watch for changes and rebuild packages, codegen, etc.
  • Run minimal dev: pnpm dev:basic (only backend and dashboard for resource-limited systems)

Testing

You should ALWAYS add new E2E tests when you change the API or SDK interface. Generally, err on the side of creating too many tests; it is super important that our codebase is well-tested, due to the nature of the industry we're building in.

  • Run all tests: pnpm test run
  • Run some tests: pnpm test run <file-filters>

Database Commands

  • Generate migration: pnpm db:migration-gen
  • Reset database (rarely used): pnpm db:reset
  • Seed database (rarely used): pnpm db:seed
  • Initialize database (rarely used): pnpm db:init
  • Run migrations (rarely used): pnpm db:migrate

Architecture Overview

Stack Auth is a monorepo using Turbo for build orchestration. The main components are:

Apps (/apps)

  • backend (/apps/backend): Next.js API backend running on port ${NEXT_PUBLIC_STACK_PORT_PREFIX:-81}02 (defaults to 8102)
    • Main API routes in /apps/backend/src/app/api/latest
    • Database models using Prisma
  • dashboard (/apps/dashboard): Admin dashboard on port ${NEXT_PUBLIC_STACK_PORT_PREFIX:-81}01 (defaults to 8101)
  • dev-launchpad: Development portal on port ${NEXT_PUBLIC_STACK_PORT_PREFIX:-81}00 (defaults to 8100)
  • e2e: End-to-end tests

Packages (/packages)

  • stack (/packages/stack): Main Next.js SDK
  • stack-shared (/packages/stack-shared): Shared utilities and types
  • stack-ui (/packages/stack-ui): UI components
  • react (/packages/react): React SDK
  • js (/packages/js): JavaScript SDK

Key Technologies

  • Framework: Next.js (with App Router)
  • Database: PostgreSQL with Prisma ORM
  • Testing: Vitest
  • Package Manager: pnpm with workspaces
  • Build Tool: Turbo
  • TypeScript: Used throughout
  • Styling: Tailwind CSS

API Structure

The API follows a RESTful design with routes organized by resource type:

  • Auth endpoints: /api/latest/auth/*
  • User management: /api/latest/users/*
  • Team management: /api/latest/teams/*
  • OAuth providers: /api/latest/oauth-providers/*

Development Ports

To see all development ports, refer to the index.html of apps/dev-launchpad/public/index.html.

Important Notes

  • NEVER UPDATE packages/stack OR packages/js. Instead, update packages/template, as the others are simply copies of that package.
  • For blocking alerts and errors, never use toast, as they are easily missed by the user. Instead, use alerts.
  • Environment variables are pre-configured in .env.development files
  • Always run typecheck, lint, and test to make sure your changes are working as expected. You can save time by only linting and testing the files you've changed (and/or related E2E tests).
  • The project uses a custom route handler system in the backend for consistent API responses
  • When writing tests, prefer .toMatchInlineSnapshot over other selectors, if possible. You can check (and modify) the snapshot-serializer.ts file to see how the snapshots are formatted and how non-deterministic values are handled.
  • Whenever you learn something new, or at the latest right before you call the Stop tool, write whatever you learned into the ./claude/CLAUDE-KNOWLEDGE.md file, in the Q&A format in there. You will later be able to look up knowledge from there (based on the question you asked).
  • Animations: Keep hover/click transitions snappy and fast. Don't delay the action with a pre-transition (e.g. no fade-in when hovering a button) — it makes the UI feel sluggish. Instead, apply transitions after the action, like a smooth fade-out when the hover ends.
  • Whenever you make changes in the dashboard, provide the user with a deep link to the dashboard page that you've just changed. Usually, this takes the form of http://localhost:<whatever-is-in-$NEXT_PUBLIC_STACK_PORT_PREFIX>01/projects/-selector-/..., although sometimes it's different. If $NEXT_PUBLIC_STACK_PORT_PREFIX is set to 91, 92, or 93, use a.localhost, b.localhost, and c.localhost for the domains, respectively.
  • To update the list of apps available, edit apps-frontend.tsx and apps-config.ts. When you're tasked to implement a new app or a new page, always check existing apps for inspiration on how you could implement the new app or page.
  • NEVER use Next.js dynamic functions if you can avoid them. Instead, prefer using a client component to make sure the page remains static (eg. prefer usePathname instead of await params).
  • Whenever you make backwards-incompatible changes to the config schema, you must update the migration functions in packages/stack-shared/src/config/schema.ts!
  • NEVER try-catch-all, NEVER void a promise, and NEVER .catch(console.error) (or similar). In most cases you don't actually need to be asynchronous, especially when UI is involved (instead, use a loading indicator! eg. our component already takes an async callback for onClick and sets its loading state accordingly — if whatever component doesn't do that, update the component instead). If you really do need things to be asynchronous, use runAsynchronously or runAsynchronouslyWithAlert instead as it deals with error logging.

Code-related

  • Use ES6 maps instead of records wherever you can.