This guide is for agentic coding assistants working in this repo. It captures how to build, test, lint, and the coding style used here.
- App: TanStack Start + Vite + React 19
- Language: TypeScript (strict)
- Styling: Tailwind CSS
- Tooling: Biome (lint/format), Vitest (tests)
- Package manager: pnpm
- Path alias:
@/*->src/*
Use pnpm unless a script explicitly says otherwise.
pnpm installpnpm devpnpm buildpnpm startpnpm lintpnpm formatpnpm testpnpm test:watchpnpm test:coverageVitest supports passing a file path after --.
pnpm test -- src/utils/__tests__/parse-times.test.tspnpm test -- -t "parses single range"pnpm test:watch -- src/utils/__tests__/course-filters.test.tsVITE_COURSES_URL(preferred)NEXT_PUBLIC_COURSES_URL(also supported by Vite env prefix)
If neither is set, the app falls back to the public GitHub JSON URL in
src/components/course-scheduler-content.tsx.
- Use Biome for formatting and linting.
- Indentation: 2 spaces (configured in
biome.json). - Use double quotes and semicolons (existing files follow this style).
- Imports are organized by Biome (
organizeImportsis on).
- Prefer
import typefor type-only imports. - Order: external packages first, then internal
@/imports, then relative. - Use the
@/alias forsrc/*instead of long relative paths.
strictmode is enabled; do not introduceany.- Use
interfacefor object shapes that may be extended; usetypefor unions and utility compositions (seesrc/types/course.ts). - Favor explicit return types when a function has complex logic or is exported from a shared utility.
- Function components only; no class components.
- Prefer named exports for shared components (e.g.
export function X). - Default exports exist in a few files; preserve existing style per file.
- Use hooks and local helpers defined above the component where appropriate.
- Add
"use client"in TanStack Start components that rely on client-only APIs.
- Data fetching uses React Query (
useQuery). - Always check
res.okand throw a descriptive error on failure. - Normalize/transform server data in
selectwhen possible (seesrc/components/course-scheduler-content.tsx).
- Prefer early returns/guards for invalid data.
- Throw
Errorwith a clear message for failed network calls. - Avoid silent failures; if a value is optional, handle the empty case
explicitly (see
parseTimes).
- Use
camelCasefor variables and functions. - Use
PascalCasefor components and exported types. - Use
UPPER_SNAKE_CASEfor constants (e.g.DAY_OPTIONS). - Files with hooks should be
use-*.ts(x).
- Tests live in
src/**/__tests__and use Vitest. - Use
describeanditwith clear, behavior-focused names. - Keep test input/expected values explicit; prefer
toEqualfor arrays/objects.
- Use
cnfromsrc/lib/utils.tsfor conditional class name merging when needed. - Keep long class lists readable; line-wrap JSX props where needed.
- Vite is configured with
envPrefix: ["VITE_", "NEXT_PUBLIC_"]. - Vitest runs in a
jsdomenvironment and includessrc/**/*.test.{ts,tsx}. - Vitest uses a setup file; see
vitest.config.tsfor the configured path. - Coverage targets utilities in
src/utils/**/*.{ts,tsx}with 80% thresholds.