This file applies to all projects. Project-level CLAUDE.md files extend or override these rules.
- Prince. Senior AI Product Manager at Flipkart. I vibe-code on weekends.
- I am not a professional engineer. I think in product terms and write code to ship things, not to impress reviewers.
- My projects run on a personal Linux server. No cloud infra, no CI/CD pipelines, no containerisation unless I explicitly ask for it.
- Explain your plan before acting — unless it's trivial. For anything that touches multiple files, changes architecture, or involves a design decision: give me 2-3 lines on what you'll do, what files you'll touch, and any tradeoffs. Then wait for confirmation. For trivial tasks (bug fixes, UI tweaks, typos, copy changes, single-line fixes) — just do it. Don't turn a one-shot fix into a multi-turn conversation.
- When in doubt, ask. Never assume. If a requirement is ambiguous, a design choice has multiple valid paths, or you're unsure what I want — stop and clarify. The only exception is truly obvious decisions (e.g. naming a variable, choosing between two equivalent imports).
- Reuse before creating. Before writing a new component, utility, or helper, check if one already exists in the codebase. If something similar exists, extend it. Do not create duplicates.
- Test what you write — proportionally. Not every change needs a full verification loop. Use this hierarchy:
- Always test: Anything touching data, database queries, API endpoints, parsers, or business logic. Run the code, check the output.
- Quick check: UI changes that affect layout or interactivity. Verify the dev server runs and the page renders.
- Trust the code: Trivial fixes (typos, copy, single-line CSS, import reordering). Don't burn tokens confirming a padding change works.
- Be direct. No filler, no preamble, no "Great question!" or "Sure, I'd be happy to help!"
- When something is broken, say what's broken and why. Don't soften it.
- If I'm making a bad decision, tell me. Explain why and suggest the better path.
- Keep explanations concrete. Use code snippets, file paths, and specific examples — not abstract descriptions.
- Python 3.11+
- FastAPI for APIs. Always use async endpoints. Bind to
127.0.0.1, not0.0.0.0. - SQLite for all databases. No Postgres, no ORMs (no SQLAlchemy). Use raw SQL via Python's
sqlite3module oraiosqlitefor async. Always usesqlite3.Rowas the row factory so results are accessible by column name. Map rows to Pydantic models usingModel.model_validate(dict(row))or explicit dictionary unpacking — never write manual tuple-index mapping. - Pydantic for request/response validation.
- Virtual environments via
python -m venv venv. Never use conda or poetry. - Use
requirements.txt, notpyproject.tomlorsetup.py. - Prefer standard library over third-party packages when the difference in effort is small.
- Next.js (App Router) with strict TypeScript. No
anytypes unless absolutely unavoidable and commented with why. - Tailwind CSS for styling. In existing projects, use whatever CSS approach the project already uses.
- npm as the package manager. Not yarn, pnpm, or bun.
- Use
"use client"only when necessary (state, effects, event handlers). Default to server components. - Prefer named exports over default exports for components.
- Indie hacker style, not enterprise. My side projects are single-user tools, not multi-service systems. Keep code readable, flat, and functional. Do not introduce Clean Architecture, Hexagonal Architecture, repository patterns, service layers, dependency injection, or abstract factory patterns unless I explicitly ask for them. A flat module with functions is almost always the right call.
- No Docker or containerisation unless I explicitly ask for it.
- No CI/CD pipeline setup. I deploy manually or via simple scripts.
.envfor secrets. Always.gitignoreit. Always provide a.env.example.- Commit messages: short and descriptive, no format enforced. Just get it done.
- Use type hints on all function signatures.
- Use
snake_casefor functions and variables,PascalCasefor classes. - Keep files focused. One module = one responsibility. But don't over-split — a 200-line file with related functions is fine.
- Use
loggingmodule, notprint(), for anything that isn't a quick debug. - Async by default for I/O operations (file reads, HTTP calls, database queries).
- Error handling: catch specific exceptions. Never bare
except:.
- Functional components only. No class components.
- Use
interfaceovertypefor object shapes unless you need union types. - Colocate related code: keep a component's types, hooks, and helpers in the same file unless they're reused elsewhere.
- Modular, reusable components. If you're writing similar JSX twice, extract it into a shared component.
- Prefer
constarrow functions for components:const Button = () => { ... } - Destructure props in the function signature.
- No commented-out code. Delete it. That's what git is for.
- No over-commenting. Comments should explain why, not what. If the code needs a comment to explain what it does, the code is too clever.
- Keep functions small. If a function is over 40 lines, it probably does too much.
- Naming: descriptive but not verbose.
getUserTransactionsis good.fetchAndReturnAllUserTransactionRecordsFromDatabaseis not.
project/
├── backend/
│ ├── src/
│ │ ├── api/ # FastAPI routes
│ │ ├── db/ # Schema, migrations, queries
│ │ ├── services/ # Business logic
│ │ └── config.py
│ ├── requirements.txt
│ └── .env.example
├── frontend/
│ ├── app/ # Next.js App Router pages
│ ├── components/ # Reusable UI components
│ ├── lib/ # Utilities, API client, types
│ ├── package.json
│ └── tsconfig.json
├── scripts/ # Setup, migration, cron scripts
├── .gitignore
├── CLAUDE.md
└── README.md
- API routes go in
backend/src/api/routes/. One file per resource. - Database queries go in
backend/src/db/. Separate from API route handlers. - Shared TypeScript types go in
frontend/lib/types.tsor atypes/directory. - Reusable React components go in
frontend/components/. Page-specific components stay in the page file until they're reused.
- Tests are not required for every change — use judgment. Write tests for:
- Data parsing logic (parsers, transformers)
- API endpoints that handle money or sensitive data
- Complex business logic with edge cases
- pytest for Python. vitest for TypeScript.
- Test files live next to the code they test:
parser.py→test_parser.py.
- Never install a dependency without telling me what it is and why it's needed.
- Never use
varin TypeScript/JavaScript. - Never use ORMs. Write SQL.
- Never use
0.0.0.0for local development servers. - Never create a new utility/component when a similar one exists. Check first.
- Never leave
TODOorFIXMEcomments without flagging them to me. - Never use
console.logfor production code. Use proper error handling or a logger. - Never modify
.env,.gitignore, or config files without explicitly telling me. - Never assume a requirement — ask me.