Files
fullstack-starter/AGENTS.md

9.1 KiB

AGENTS.md - AI Coding Agent Guidelines

Guidelines for AI agents working in this Bun monorepo.

Project Overview

This project uses Bun exclusively as both the JavaScript runtime and package manager. Do NOT use Node.js / npm / yarn / pnpm. All commands start with bun — use bun install for dependencies and bun run / bun <script> for scripts. Never use npm, npx, or node.

  • Monorepo: Bun workspaces + Turborepo orchestration
  • Runtime: Bun (see mise.toml for version) — NOT Node.js
  • Package Manager: Bun — NOT npm / yarn / pnpm
  • Apps:
    • apps/server - TanStack Start fullstack web app (see apps/server/AGENTS.md)
    • apps/desktop - Electron desktop shell, sidecar server pattern (see apps/desktop/AGENTS.md)
  • Packages: packages/tsconfig (shared TS configs)

Build / Lint / Test Commands

Root Commands (via Turbo)

bun dev            # Start all apps in dev mode
bun build          # Build all apps
bun compile        # Compile server to standalone binary (current platform, depends on build)
bun compile:linux  # Compile server for Linux binaries (x64 + arm64)
bun compile:darwin # Compile server for macOS binaries (arm64 + x64)
bun compile:windows # Compile server for Windows x64 binary
bun dist           # Full packaging pipeline: server build → compile → desktop distributable (current platform)
bun dist:linux     # Full pipeline → Linux distributables (x64 + arm64)
bun dist:mac       # Full pipeline → macOS distributables (arm64 + x64)
bun dist:win       # Full pipeline → Windows distributable
bun fix            # Lint + format (Biome auto-fix)
bun typecheck      # TypeScript check across monorepo

Server App (apps/server)

bun dev                   # Vite dev server (localhost:3000)
bun build                 # Production build -> .output/
bun compile               # Compile to standalone binary (current platform)
bun compile:darwin        # Compile for macOS (arm64 + x64)
bun compile:darwin:arm64  # Compile for macOS arm64
bun compile:darwin:x64    # Compile for macOS x64
bun compile:linux         # Compile for Linux (x64 + arm64)
bun compile:linux:arm64   # Compile for Linux arm64
bun compile:linux:x64     # Compile for Linux x64
bun compile:windows       # Compile for Windows (default: x64)
bun compile:windows:x64   # Compile for Windows x64
bun fix                   # Biome auto-fix
bun typecheck             # TypeScript check

# Database (Drizzle)
bun db:generate           # Generate migrations from schema
bun db:migrate            # Run migrations
bun db:push               # Push schema (dev only)
bun db:studio             # Open Drizzle Studio

Desktop App (apps/desktop)

bun dev                   # electron-vite dev mode (requires server dev running)
bun build                 # electron-vite build (main + preload)
bun dist                  # Build + package for current platform
bun dist:linux            # Build + package for Linux (x64 + arm64)
bun dist:linux:x64        # Build + package for Linux x64
bun dist:linux:arm64      # Build + package for Linux arm64
bun dist:mac              # Build + package for macOS (arm64 + x64)
bun dist:mac:arm64        # Build + package for macOS arm64
bun dist:mac:x64          # Build + package for macOS x64
bun dist:win              # Build + package for Windows x64
bun fix                   # Biome auto-fix
bun typecheck             # TypeScript check

Testing

No test framework configured yet. When adding tests:

bun test path/to/test.ts              # Run single test file
bun test -t "pattern"                 # Run tests matching pattern

Code Style (TypeScript)

Formatting (Biome)

  • Indent: 2 spaces | Line endings: LF
  • Quotes: Single ' | Semicolons: Omit (ASI)
  • Arrow parentheses: Always (x) => x

Imports

Biome auto-organizes. Order: 1) External packages → 2) Internal @/* aliases → 3) Type imports (import type { ... })

import { createFileRoute } from '@tanstack/react-router'
import { z } from 'zod'
import { db } from '@/server/db'
import type { ReactNode } from 'react'

TypeScript Strictness

  • strict: true, noUncheckedIndexedAccess: true, noImplicitOverride: true, verbatimModuleSyntax: true
  • Use @/* path aliases (maps to src/*)

Naming Conventions

Type Convention Example
Files (utils) kebab-case auth-utils.ts
Files (components) PascalCase UserProfile.tsx
Components PascalCase arrow const Button = () => {}
Functions camelCase getUserById
Constants UPPER_SNAKE MAX_RETRIES
Types/Interfaces PascalCase UserProfile

React Patterns

  • Components: arrow functions (enforced by Biome)
  • Routes: TanStack Router file conventions (export const Route = createFileRoute(...))
  • Data fetching: useSuspenseQuery(orpc.feature.list.queryOptions())
  • Let React Compiler handle memoization (no manual useMemo/useCallback)

Error Handling

  • Use try-catch for async operations; throw descriptive errors
  • ORPC: Use ORPCError with proper codes (NOT_FOUND, INPUT_VALIDATION_FAILED)
  • Never use empty catch blocks

Database (Drizzle ORM v1 beta + postgres-js)

  • ORM: Drizzle ORM 1.0.0-beta (RQBv2)
  • Driver: drizzle-orm/postgres-js (NOT bun-sql)
  • Validation: drizzle-orm/zod (built-in, NOT separate drizzle-zod package)
  • Relations: Defined via defineRelations() in src/server/db/relations.ts (contains schema info, so drizzle() only needs { relations })
  • Query style: RQBv2 object syntax (orderBy: { createdAt: 'desc' }, where: { id: 1 })
export const myTable = pgTable('my_table', {
  id: uuid().primaryKey().default(sql`uuidv7()`),
  name: text().notNull(),
  createdAt: timestamp({ withTimezone: true }).notNull().defaultNow(),
  updatedAt: timestamp({ withTimezone: true }).notNull().defaultNow().$onUpdateFn(() => new Date()),
})

Environment Variables

  • Use @t3-oss/env-core with Zod validation in src/env.ts
  • Server vars: no prefix | Client vars: VITE_ prefix required
  • Never commit .env files

Dependency Management

  • All versions centralized in root package.json catalog field
  • Workspace packages use "catalog:" — never hardcode versions
  • Internal packages use "workspace:*" references

Development Principles

These principles apply to ALL code changes. Agents MUST follow them on every task.

  1. No backward compatibility — This project is in rapid iteration. Always use the latest API and patterns. Never keep deprecated code paths or old API fallbacks "just in case".
  2. Always sync documentation — When code changes, immediately update all related documentation (AGENTS.md, README.md, inline code examples). Code and docs must never drift apart. This includes updating code snippets in docs when imports, APIs, or patterns change.
  3. Forward-only migration — When upgrading dependencies, fully adopt the new API. Don't mix old and new patterns in the same codebase.

Critical Rules

DO:

  • Run bun fix before committing
  • Use @/* path aliases (not relative imports)
  • Include createdAt/updatedAt on all tables
  • Use catalog: for dependency versions
  • Update AGENTS.md and other docs whenever code patterns change

DON'T:

  • Use npm, npx, node, yarn, pnpm — always use bun / bunx
  • Edit src/routeTree.gen.ts (auto-generated)
  • Use as any, @ts-ignore, @ts-expect-error
  • Commit .env files
  • Use empty catch blocks catch(e) {}
  • Hardcode dependency versions in workspace packages
  • Leave docs out of sync with code changes

Git Workflow

  1. Make changes following style guide
  2. bun fix - auto-format and lint
  3. bun typecheck - verify types
  4. bun dev - test locally
  5. Commit with descriptive message

Directory Structure

.
├── apps/
│   ├── server/           # TanStack Start fullstack app
│   │   ├── src/
│   │   │   ├── client/   # ORPC client, Query client
│   │   │   ├── components/
│   │   │   ├── routes/   # File-based routing
│   │   │   └── server/   # API layer + database
│   │   │       ├── api/  # ORPC contracts, routers, middlewares
│   │   │       └── db/   # Drizzle schema
│   │   └── AGENTS.md
│   └── desktop/          # Electron desktop shell
│       ├── src/
│       │   ├── main/
│       │   │   └── index.ts       # Main process entry
│       │   └── preload/
│       │       └── index.ts       # Preload script
│       ├── electron.vite.config.ts
│       ├── electron-builder.yml   # Packaging config
│       └── AGENTS.md
├── packages/
│   └── tsconfig/         # Shared TS configs
├── biome.json            # Linting/formatting config
├── turbo.json            # Turbo task orchestration
└── package.json          # Workspace root + dependency catalog

See Also

  • apps/server/AGENTS.md - Detailed TanStack Start / ORPC patterns
  • apps/desktop/AGENTS.md - Electron desktop development guide