Use this skill whenever the user wants to create a new software project, scaffold a codebase, add features to an existing project, design system architecture, generate boilerplate, or build out a multi-file codebase in any programming language. Trigger this skill for requests involving project setup, code generation at scale, adding modules or services, refactoring large codebases, or any task where multiple files need to be created or modified in a coordinated way. Also trigger when the user says things like "build me a...", "create a project for...", "scaffold a...", "set up a...", "architect a...", "implement a system that...", or provides a requirements doc and expects working code. Even partial cues like "add a new service", "set up the backend", "create the API layer", or "wire up the database" should trigger this skill. If in doubt and the task involves generating or organizing code across files, use this skill.
A skill for building software projects of any size, in any language, using an architecture-first approach. The skill adapts its workflow to the project's nature, respects existing codebases, and maintains a local memory so context is preserved across conversations.
Every line of generated code should be something a senior engineer would approve in code review. The skill is opinionated about quality but flexible about everything else: language, framework, scale, and delivery all adapt to context.
These apply to every file, every function, every line, regardless of language:
SOLID principles always. Single Responsibility, Open/Closed, Liskov Substitution, Interface Segregation, Dependency Inversion. These are not aspirational; they are the baseline.
Immutability by default. Every variable, field, parameter, and data structure is immutable unless mutation is explicitly required and justified. Use the language's strongest immutability idiom:
& borrows, use only when neededmuttuple over list for fixed data, use Final from typing, frozen dataclassesfinal on every variable/field/parameter by default, @Value classes via Lombokconst, readonly, Readonly<T>, as constZero hardcoded values. All constants, magic numbers, configuration values, URLs, timeouts, feature flags, and similar go into a centralized constants or config file (or module). Every other file references these through imports. The constants file should be well-organized with clear grouping and documentation.
No raw nulls. Use Optional/Option/Result types everywhere. Never return or accept null/None/nil where an Optional type exists in the language. Handle absence explicitly.
Prefer standard library utilities. If the language or its standard library provides a utility, use it. Do not reimplement Objects.isNull, Comparator.comparing, itertools, std::cmp, or anything else the platform already offers. Check before writing.
Self-explanatory code, no comments. Code must read like well-written prose. Use descriptive variable names, function names, class names, and module structure to convey intent. Do not add inline comments, block comments, or documentation comments inside code files. If you feel the need to write a comment, that is a signal to rename, restructure, or extract a function instead. The only exceptions are: (a) legal/license headers if required by the project, and (b) TODO markers for genuinely unfinished work tracked in tasklist.md.
Code like a senior engineer. Write code as a highly experienced senior software engineer would. This means: choosing the right abstraction level (not too clever, not too naive), anticipating edge cases, designing for change, naming things precisely, keeping functions small and focused, avoiding premature optimization but not ignoring performance, and preferring clarity over brevity. Every file should pass a strict code review from a principal engineer without pushback.
Break down before building. Never start implementing a large requirement as a monolith. Decompose every problem into small, well-defined, independently testable tasks. Write these into .claude/context/tasklist.md and .claude/context/plan.md before writing any implementation code. Follow the plan throughout, checking off tasks as they complete. If the scope changes mid-work, update the plan first, then continue.
Testing is not optional. Every feature, module, and significant function must be covered by tests. Write unit tests for individual logic and integration tests for module boundaries and API endpoints. Tests are written alongside implementation, not after. Use the ecosystem's standard test framework. Test names describe behavior, not implementation (e.g., should_return_empty_when_no_items_found not test_get_items). Cover edge cases: empty inputs, boundary values, error conditions, null/absent values.
Follow up with the user. Do not assume. When requirements are ambiguous, when there are multiple valid approaches, when a decision has significant trade-offs, or when something seems off, stop and ask the user. Present the options clearly, explain the trade-offs, and let them decide. It is always better to ask one clarifying question than to build the wrong thing. After completing significant milestones, check in with the user before proceeding to the next phase.
Protocol classes for structural subtyping (duck typing with safety). Prefer protocols over ABCs when the consumer shouldn't care about inheritance.typing module usage: Optional, Final, TypeAlias, TypeVar, Generic, Literal, TypedDict, Annotated, overload, and others as appropriate.NamedTuple for data containers. Mutable classes need justification.from __future__ import annotations for modern annotation behavior.java.util.Optional for any value that might be absent. Use java.util.Objects.isNull(), Objects.nonNull(), Objects.requireNonNull() rather than manual null checks.@Value for immutable data classes (preferred default over @Data)@Builder on classes and records@NonNull on parameters and fields that must not be null@Getter + @RequiredArgsConstructor on enums@Slf4j for logging@Builder for simple data carriers.Comparator.comparing(), Stream API, Collections.unmodifiable*(), Map.of(), List.of(), etc.Result<T, E> for fallible operations, define meaningful error types (consider thiserror or anyhow).Clone, Debug, PartialEq etc. as appropriate. Use #[non_exhaustive] on public enums/structs.impl Trait in argument position for flexibility."strict": true in tsconfig).const by default, let only when reassignment is unavoidable, never var.readonly on object properties. Readonly<T>, ReadonlyArray<T>..claude/context/Every project gets a local memory directory at <project_root>/.claude/context/. This is the project's single source of truth: a persistent lookup reference that eliminates the need to re-analyze the project on every interaction. Think of it as the project's brain. Build it once, keep it updated, and always consult it before doing anything.
The deep dive in Step 0 populates these files. After that, they serve as the fast-access reference so you never have to re-discover what you already know.
| File | Purpose | When to update |
|---|---|---|
architecture.md | High-level system design, component relationships, data flow, key design decisions and their rationale | On project creation, and whenever a significant architectural decision is made |
conventions.md | Coding patterns, naming conventions, file organization rules, import ordering, error handling patterns. For existing codebases, this captures discovered patterns. | On project creation (from analysis of existing code or from decisions made), whenever a new convention is established |
progress.md | What modules/features are complete, what's in progress, what's pending. A living changelog. | After every significant piece of work |
constants-map.md | Where config/constants files live, what groups of constants they contain, how to add new ones | On project creation, whenever constants files are added or reorganized |
dependencies.md | Key libraries/frameworks chosen, why they were chosen (over alternatives), version constraints, compatibility notes | On project creation, whenever a new dependency is added |
tasklist.md | Breakdown of all planned work items, ordered by priority/dependency. Checkboxes for tracking. Includes current phase and next steps. | On project creation, updated as tasks complete or new ones emerge |
plan.md | The overall project plan: phases, milestones, delivery strategy, risk areas, open questions | On project creation, updated at phase transitions |
.claude/context/.gitignore: append .claude/context/ (it's development scaffolding, not source code).dockerignore if a Dockerfile exists or is being createdThe skill does not follow a single rigid process. It assesses the project and picks the right approach. But one thing is absolute: understand the project completely before writing a single line of code.
This is the most important step. Whether the project is new or existing, the very first action is to build a complete understanding of the project and persist it in .claude/context/. This investment upfront eliminates costly re-discovery, inconsistencies, and wasted iterations later.
Walk through the entire codebase systematically before making any changes:
Scan the full directory tree: understand every directory's purpose, how modules are organized, what lives where
Read all key files thoroughly: entry points, configuration files, build configs, existing constants/config files, environment files, CI configs, Docker configs, test setup, dependency manifests (package.json, Cargo.toml, pom.xml, pyproject.toml, etc.)
Trace the architecture: how do components connect? What's the data flow? What patterns are used for dependency injection, error handling, logging, validation, routing?
Catalog coding conventions: naming style (camelCase, snake_case, prefix patterns), import ordering, comment style, indentation, quote style, file naming patterns, module structure, abstraction patterns, how tests are organized
Map constants and config: find all existing constants files, env files, config objects. Understand how configuration flows through the system.
Identify the tech stack: frameworks, libraries, build tools, test frameworks, linters, formatters, and their versions
Write everything to .claude/context/:
architecture.md: full system map with component relationships, data flow, integration pointsconventions.md: every coding pattern discovered, with file references as examplesdependencies.md: all libraries, their roles, version constraintsconstants-map.md: where all config/constants live, what they containprogress.md: current state of the project (what exists, what's complete, what's partial)tasklist.md: planned work items based on the user's requestplan.md: approach for the requested changesFollow what you find. Generated code must look like the existing team wrote it. Match every convention exactly.
Before generating any files, build the full mental model:
.claude/context/: populate all seven context files before generating any project code. This is the blueprint; the code follows from it.When returning to a project that already has .claude/context/:
progress.md and tasklist.md to understand where things left off.After the deep dive, determine the right execution strategy:
What's the scale?
What language and ecosystem? This determines tooling (package manager, testing framework, linter, formatter, etc.)
What's the delivery context? Determines doc format (markdown in-repo, docx for external, both), packaging (zip, direct files), and what extras to include (Docker, CI, DB migrations).
For new projects or major features:
.claude/context/ directory and populate:
architecture.md: component diagram, data flow, key interfaces, design decisionsplan.md: phased delivery plan tailored to project scaletasklist.md: granular task breakdown ordered by dependency, with checkboxesdependencies.md: chosen libraries with rationaleconventions.md: coding standards for this projectconstants-map.md: planned constants/config structureGenerate the project structure with all files present but implementation deferred where appropriate:
.gitignore, .dockerignore with .claude/context/ includedFill in the skeleton module by module, strictly following the tasklist:
tasklist.mdprogress.md after each moduleconstants-map.md when new constants are addedconventions.md regularly to stay consistentplan.md and consult the userAdapt to what makes sense:
.tar.gz or .zip.docx if the user needs it for external sharingTesting is a first-class part of every task, not an afterthought:
should_reject_expired_token not test_validate)tasklist.md should have associated tests before it can be marked completeWhen the project involves a database:
architecture.mdWhen Docker is appropriate:
.dockerignore that excludes .claude/context/, test files, docs, and dev dependenciesdocker-compose.yml for local development with all services (DB, cache, etc.)Before presenting generated code, verify:
.claude/context/ created and populated.claude/context/ added to .gitignore and .dockerignoretasklist.md and plan.md written before implementation beganconstants-map.md