Files
fullstack-starter/AGENTS.md

6.3 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 - Electrobun desktop shell, loads server in native window (see apps/desktop/AGENTS.md)
  • Packages: packages/utils, packages/tsconfig (shared configs)

Build / Lint / Test Commands

Root Commands (via Turbo)

bun dev            # Start all apps in dev mode
bun build          # Build all apps
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
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                   # Start Electrobun dev mode (requires server dev running)
bun build                 # Build canary release
bun build:stable          # Build stable release
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)

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

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

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

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/          # Electrobun desktop shell
│       ├── src/
│       │   └── bun/
│       │       └── index.ts       # Main process entry
│       ├── electrobun.config.ts   # Electrobun configuration
│       └── AGENTS.md
├── packages/
│   ├── tsconfig/         # Shared TS configs
│   └── utils/            # Shared utilities
├── 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 - Electrobun desktop development guide