# .manovikrules — Next.js 15 App Router
- Use the App Router under /app. Never create /pages files.
- Default to Server Components. Add "use client" only when you need state, effects, or browser APIs.
- Fetch data in server components with async/await; never useEffect for initial loads.
- Use next/image for all raster images; set width, height, and alt.
- Style with Tailwind v4 tokens (bg-background, text-foreground); never hardcode hex.
- Shared UI lives in components/ui (shadcn). Route-specific components live next to the route.
- Use zod for all form and API input validation.
- Prefer Route Handlers under app/api/*/route.ts for server endpoints.
- Never commit secrets. Read them via process.env inside server code only.
# .manovikrules — TanStack Start
- All routes live in src/routes; never install react-router-dom.
- Use createFileRoute for pages and createServerFn from @tanstack/react-start for server logic.
- Fetch initial data in loaders via context.queryClient.ensureQueryData; render with useSuspenseQuery.
- Never edit src/routeTree.gen.ts — it is auto-generated.
- Read process.env inside .handler() only; use import.meta.env.VITE_* in the browser.
- Protected server functions use .middleware([requireSupabaseAuth]).
- Webhooks and public APIs go under src/routes/api/public/*.
- Head metadata: every leaf route sets its own title, description, og:*, twitter:card.
# .manovikrules — React + Tailwind + shadcn
- Use semantic tokens (bg-background, text-foreground, text-muted-foreground) — never bg-white/text-black or arbitrary hex.
- Icon-only buttons MUST include aria-label.
- Wrap the primary route content in exactly one <main>.
- Prefer shadcn primitives over hand-rolled Dialogs, Popovers, or Comboboxes.
- Keep components under ~200 lines; extract sub-components early.
- Use lucide-react for icons; import only what you use.
- Use useId() for form control ids inside list-rendered items to avoid duplicates.
- Colocate types with the component; export only what other files import.
# .manovikrules — FastAPI
- Use async def for all route handlers unless they are trivially sync.
- Validate every request/response body with pydantic v2 models; never accept dict[str, Any].
- Group routes by domain in routers/ and register them in main.py.
- Auth belongs in a Depends() dependency, not in route bodies.
- Never call blocking IO in a request path — use httpx.AsyncClient, asyncpg, or run_in_threadpool.
- Log with structlog; include request_id and user_id when available.
- Use ruff + mypy --strict; no untyped defs allowed.
- Tests use pytest-asyncio + httpx.AsyncClient against the ASGI app.
# .manovikrules — Django 5 + DRF
- Model changes go through makemigrations + migrate — never edit historical migrations.
- Serializers validate input; never trust request.data directly.
- Business logic lives in services/, not in views or serializers.
- Use select_related / prefetch_related on every list endpoint that renders relations.
- Permission classes gate every viewset; default deny.
- Use django-environ for settings; secrets never touch settings.py.
- Tests use pytest-django with factory_boy fixtures.
# .manovikrules — Tailwind v4
- Define tokens in @theme inside styles.css; no tailwind.config.js.
- Keep all @import rules at the very top of styles.css, before @theme.
- Never @import a remote URL — load web fonts via <link> in the root head.
- Use CSS variables (hsl(var(--primary))) inside @theme, not raw hex.
- Prefer @utility for one-off utilities over inline arbitrary values.
- Dark mode: use @custom-variant dark (&:where(.dark, .dark *)); toggle .dark on <html>.
# .manovikrules — Expo (React Native)
- Use expo-router; routes live under app/. Never mix with react-navigation stacks.
- Prefer expo-image over Image for caching and blurhash.
- Use react-native-reanimated for animation, not Animated.
- All native modules must have an Expo config plugin or be part of Expo SDK.
- Ship with EAS Build; never commit ios/ or android/ unless the project uses bare workflow.
- Use SafeAreaView from react-native-safe-area-context for every screen root.
- Handle offline: wrap network calls with react-query and set retry + staleTime.
# .manovikrules — Supabase
- Every new public table: CREATE TABLE, then GRANT, then ENABLE RLS, then CREATE POLICY — in that order.
- Never store roles on profiles; use a separate user_roles table + has_role() security-definer function.
- Never call supabase.auth.admin from client code; use it only in server functions.
- Generated types live in integrations/supabase/types.ts — never hand-edit.
- Migrations are append-only; new file per change.
- Anon key is safe to ship; service_role never touches the browser bundle.
# .manovikrules — Node.js + TypeScript
- ESM only ("type": "module"); no require().
- tsconfig: strict, noUncheckedIndexedAccess, exactOptionalPropertyTypes.
- Validate every external input (env, HTTP, queue payloads) with zod.
- Never throw strings — always Error subclasses with a machine-readable code.
- Structured logging via pino; correlate with a request id.
- HTTP client: undici fetch, not axios.
- Tests: vitest with 100% type coverage on public APIs.
# .manovikrules — Monorepo
- Apps live in apps/*, shared libraries in packages/*.
- No app imports another app; cross-app code goes into packages/.
- Every package exports through its package.json "exports" field; no deep imports.
- Shared tsconfig, eslint, and prettier live in packages/config.
- Use turbo run build --filter for scoped builds; never turbo run build with no filter in CI.
- Bump versions with changesets; no manual package.json edits.