- Runtime / build: Bun, Vite 7
- UI: React 19
- Lint/format: biomejs.dev. Notable: import sorting, strict switch-case, class sorting; formatter lineWidth 100, semicolons asNeeded, single quotes;
css.parser.tailwindDirectives: true;useHookAtTopLevelerror,useExhaustiveDependencieswarn. - Data: tanstack.com/query, TanStack Form (for non-trivial forms)
- Routing: TanStack Router
- State: Zustand (tkdodo); URL state via nuqs with one hook file per state
- Styling: Tailwind CSS, @tailwindcss/forms, @tailwindcss/typography, tailwind-merge with
twJoin,twMerge - Fonts: Fontsource imports
- Tests: Vitest, maybe Playwright
- Zod 4
- Maplibre GL JS, React Map GL, Maptiler basemap
- Prefer React Map GL event handlers; avoid raw Maplibre when avoidable
- Use
interactiveLayerIdsand pre-filtered map.featuresin handlers (see React Map GL docs) - Turf
- URL state: nuqs for all shareable UI state; one hook file per state
- Global state: Zustand for non-URL state
- Local:
useState
- No return types
- Use
type, notinterface