Skip to content

Codebase Discovery Guide

Before writing a PRD, understand the project’s existing conventions. This checklist ensures the PRD aligns with how the project actually works.

When time or context is limited, cover at least these three items:

  1. Package manager / build system — Detect the lockfile and use the correct commands everywhere
  2. Existing test and lint commands — These become mandatory quality gates
  3. Framework and language — Determines what conventions to recommend

If you can do nothing else, get these three right. The full checklist below provides deeper context.

Detect which is in use (check only one should exist):

FilePackage Manager / Build System
bun.lockb or bun.lockBun
yarn.lockYarn
pnpm-lock.yamlpnpm
package-lock.jsonnpm
deno.lockDeno
Cargo.lockCargo (Rust)
go.sumGo modules
Pipfile.lockPython (pipenv)
poetry.lockPython (Poetry)
uv.lockPython (uv)
requirements.txtPython (pip)
Gemfile.lockRuby (Bundler)
build.gradle / build.gradle.ktsJava/Kotlin (Gradle)
pom.xmlJava (Maven)
Package.swiftSwift (SPM)
pubspec.lockDart/Flutter (pub)
mix.lockElixir (Mix)
composer.lockPHP (Composer)

All PRD commands must use the detected package manager. Never mix managers.

JavaScript/TypeScript — Check package.json scripts for:

  • build - Build command and output
  • dev - Development server
  • test - Test runner and framework
  • lint - Linter configuration
  • format - Formatter configuration
  • check or typecheck - Type checking
  • start - Production start

Python — Check Makefile, pyproject.toml [tool.scripts], tox.ini, or noxfile.py for:

  • Test commands (pytest, unittest)
  • Linting (ruff, flake8, pylint)
  • Formatting (black, ruff format)
  • Type checking (mypy, pyright)

Rust — Check Cargo.toml and Makefile for:

  • cargo build, cargo test, cargo clippy, cargo fmt

Go — Check Makefile or scripts for:

  • go build, go test, go vet, golangci-lint

Quality gates are additive. Every command discovered above becomes a required quality gate. Do not pick a subset — if the project has build, test, lint, format, and check commands, all five must pass. List each one explicitly in the PRD’s quality gates section with its exact command.

Detect the project’s actual gate commands first (from the package manager / build system above and the project’s scripts); the commands below are examples to adapt, not defaults to copy. For a JS/TS project the placeholder <package-manager> is bun, npm, pnpm, or yarn:

QG-1: <package-manager> run check # Type checking
QG-2: <package-manager> run format # Formatting verification
QG-3: <package-manager> run lint # Linting
QG-4: <package-manager> run test # Test suite
QG-5: <package-manager> run build # Build succeeds

For non-JS stacks, map each gate to the project’s real toolchain:

StackType-checkFormatLintTestBuild
JS/TS (bun)bun run checkbun run formatbun run lintbun run testbun run build
JS/TS (npm/pnpm)npm run typechecknpm run formatnpm run lintnpm testnpm run build
Pythonmypy .ruff format --checkruff checkpytest
Rustcargo fmt --checkcargo clippycargo testcargo build
Gogo vet ./...gofmt -l .golangci-lint rungo test ./...go build ./...
Swift / iOSswift-format lintswiftlintswift test · xcodebuild testswift build · xcodebuild build
Android./gradlew spotlessCheck./gradlew lint./gradlew test./gradlew assemble

Identify the primary framework:

  • JavaScript/TypeScript: Check package.json dependencies for Next.js, React, Vue, Svelte, Express, Fastify, Hono, etc. Check for next.config.*, vite.config.*, nuxt.config.*, etc.
  • Python: Check for Django (manage.py), Flask/FastAPI (app.py), or framework imports
  • Rust: Check Cargo.toml dependencies for Actix, Axum, Rocket, etc.
  • Go: Check go.mod for Gin, Echo, Fiber, Chi, or standard library net/http
  • Note the routing pattern (file-based, code-based)
  • Identify server-side vs client-side rendering approach

Observe and document:

  • Source directory layout (src/, app/, lib/, packages/, cmd/, internal/)
  • Naming conventions (kebab-case, camelCase, PascalCase, snake_case for files and directories)
  • Import patterns (path aliases, barrel exports, absolute vs relative)
  • Component organization pattern
  • Monorepo detection: Check for turbo.json, nx.json, lerna.json, workspace config in package.json, or multiple go.mod files. Note workspace boundaries and shared package patterns.

Check for:

  • ORM/query builder (prisma/, drizzle/, sqlalchemy, diesel, gorm, schema files)
  • Database type (PostgreSQL, MySQL, SQLite, MongoDB, Redis)
  • Migration patterns and tools
  • Data validation libraries (Zod, Joi, Yup, Pydantic, serde)

Identify:

  • Test framework (Jest, Vitest, Playwright, Cypress, pytest, Go testing, Rust #[test], RSpec)
  • Test file location conventions (__tests__/, *.test.*, *.spec.*, tests/, _test.go)
  • Test utilities and fixtures patterns
  • Coverage requirements if configured
  • E2E test infrastructure

Check .github/workflows/, .gitlab-ci.yml, Jenkinsfile, Makefile, or similar for:

  • Which checks run on PRs
  • Required status checks
  • Deployment pipeline stages
  • Environment configurations

Check for:

  • ESLint / Biome / oxlint / ruff / clippy configuration and rules
  • Prettier / dprint / Biome / black / rustfmt formatting rules
  • TypeScript strictness level / mypy strictness / Rust edition
  • Custom lint rules or plugins

Check for:

  • Authentication patterns (JWT, session, OAuth providers, middleware)
  • Secrets management (.env patterns, vault integration, environment variable conventions)
  • Dependency audit tools (npm audit, pip-audit, cargo audit, Dependabot/Renovate config)
  • Input validation and sanitization patterns
  • CORS configuration
  • CSP headers or security middleware

Reference findings directly in the PRD:

  • Tech Stack Alignment: “Use [detected framework] with [detected package manager]”
  • Testing Strategy: “Run existing [test command] suite; add tests following [detected pattern]
  • Quality Gates: “All existing CI checks must pass: [list detected commands]
  • File Organization: “Follow existing convention: [detected pattern]
  • New Dependencies: Justify against what already exists — prefer extending current tools

If the project has no existing code (greenfield), note this and recommend conventions based on the chosen stack rather than discovered ones.