Architecture pattern selection, folder structures, coding conventions, error handling, testing strategies, and platform-specific patterns for structuring application code
Generates application architecture patterns, folder structures, and coding conventions for structuring code based on project requirements.
npx claudepluginhub navraj007in/architecture-cowork-pluginThis skill inherits all available tools. When active, it can use any tool Claude has access to.
Authoritative reference for selecting and applying the application_patterns manifest block during blueprint generation. Covers architecture pattern selection, folder structures, coding conventions, error handling, testing strategies, and platform-specific patterns.
For security architecture (auth, OWASP, API security), see operational-patterns. For infrastructure and tooling decisions (cloud, database, hosting), see prescriptive-decision-framework.
| Input | How to Determine |
|---|---|
| Team size | Gating question 5 or tech constraints section |
| Domain complexity | Simple CRUD (< 10 entities) vs complex business rules vs event-heavy workflows |
| Deployment model | Single deployable vs multiple services (from scale/team gating) |
| Platform | Backend API, frontend web app, mobile app, or full-stack |
IF simple CRUD app with < 10 entities AND team <= 3:
-> RECOMMEND: layered
-> REASONING: "Simplest to build and hire for. Controllers -> services -> data access. No abstraction overhead."
-> ALTERNATIVE: "mvc if server-rendered pages are needed (admin panels, forms)"
-> DON'T USE: "clean-architecture or hexagonal — overkill for simple CRUD"
ELSE IF server-rendered pages with forms (admin panels, CRM, dashboards):
-> RECOMMEND: mvc
-> REASONING: "Natural fit for request/response with views. Well-understood by most developers."
-> ALTERNATIVE: "layered if API-only with separate frontend"
-> DON'T USE: "cqrs, event-driven — wrong paradigm for form-based apps"
ELSE IF mobile or reactive UI with data-binding (React Native, Flutter):
-> RECOMMEND: mvvm
-> REASONING: "ViewModel decouples business logic from UI. Natural fit for reactive/declarative frameworks."
-> ALTERNATIVE: "clean-architecture if domain logic is complex beyond UI state"
-> DON'T USE: "mvc — poor fit for reactive/declarative UI frameworks"
ELSE IF complex business logic with many domain rules AND high testability needed:
-> RECOMMEND: clean-architecture
-> REASONING: "Domain at center, dependencies point inward. Business logic testable without framework/DB. Best for long-lived codebases."
-> ALTERNATIVE: "hexagonal if swappable external integrations matter more than layered use-case organization"
-> DON'T USE: "For MVPs or simple CRUD — the abstraction overhead slows early development"
ELSE IF many external integrations that may change (payment providers, notification services, AI providers):
-> RECOMMEND: hexagonal
-> REASONING: "Ports and adapters. Swap Stripe for Adyen, swap OpenAI for Anthropic — without touching business logic."
-> ALTERNATIVE: "clean-architecture if the domain rules are more complex than the integration surface"
ELSE IF single deployable AND team 3-10 AND multiple bounded contexts:
-> RECOMMEND: modular-monolith
-> REASONING: "Module isolation without deployment complexity. Each module owns its data/logic. Can extract to microservices later."
-> ALTERNATIVE: "clean-architecture if there's one dominant domain, not multiple contexts"
-> DON'T USE: "microservices — same organizational benefit, 5x more operational complexity at this team size"
ELSE IF team > 10 backend engineers AND services need independent deployment and scaling:
-> RECOMMEND: microservices
-> REASONING: "Independent deploys, independent scaling, independent tech choices per service. Required at this team size for velocity."
-> DON'T USE: "At MVP stage or with < 5 engineers — operational overhead destroys velocity"
ELSE IF low-traffic bursty workloads AND no persistent connections:
-> RECOMMEND: serverless
-> REASONING: "Pay per invocation. Auto-scales to zero. Ideal for webhooks, cron jobs, event processors."
-> ALTERNATIVE: "layered on Railway/Render if you need persistent connections (WebSockets)"
-> DON'T USE: "For real-time features, long-running jobs, or latency-sensitive APIs (cold starts)"
ELSE IF components react to events asynchronously (order placed -> email + inventory + analytics):
-> RECOMMEND: event-driven
-> REASONING: "Decouples producers from consumers. New consumers don't require changes to producers. Natural for async workflows."
-> ALTERNATIVE: "cqrs if read/write asymmetry is the primary concern rather than event flow"
-> DON'T USE: "Simple request/response CRUD — adds unnecessary complexity"
ELSE IF read and write patterns are fundamentally different (high-read dashboards + low-write mutations):
-> RECOMMEND: cqrs
-> REASONING: "Separate read models (optimized for queries) from write models (optimized for business rules). Scale reads independently."
-> ALTERNATIVE: "event-driven if the asymmetry is about workflow rather than read/write patterns"
-> DON'T USE: "Simple CRUD where reads and writes use the same model"
ELSE (default):
-> RECOMMEND: layered
-> REASONING: "Safe default. Easiest to hire for. Can evolve to modular-monolith or clean-architecture when complexity justifies it."
| Primary Pattern | Combines Well With | Avoid Combining With |
|---|---|---|
| clean-architecture | domain-driven folders, cqrs | flat folders |
| hexagonal | domain-driven folders, event-driven | layer-based folders |
| mvc | layer-based folders | cqrs, event-driven |
| mvvm | feature-based folders | microservices |
| modular-monolith | module-based folders, event-driven | flat folders |
| microservices | event-driven, cqrs | mvc, flat folders |
| serverless | flat or feature-based folders | modular-monolith |
| event-driven | cqrs, microservices, feature-based | mvc |
| cqrs | event-driven, clean-architecture | flat folders, mvc |
| layered | layer-based or feature-based folders | cqrs (overkill) |
src/
features/
auth/
auth.controller.ts
auth.service.ts
auth.repository.ts
auth.routes.ts
auth.types.ts
__tests__/
auth.service.test.ts
orders/
orders.controller.ts
orders.service.ts
orders.repository.ts
orders.routes.ts
orders.types.ts
__tests__/
orders.service.test.ts
shared/
middleware/
auth.middleware.ts
error.middleware.ts
utils/
types/
config/
env.ts
index.ts
src/
controllers/
auth.controller.ts
orders.controller.ts
services/
auth.service.ts
orders.service.ts
repositories/
auth.repository.ts
orders.repository.ts
models/
user.model.ts
order.model.ts
routes/
auth.routes.ts
orders.routes.ts
middleware/
auth.middleware.ts
error.middleware.ts
config/
env.ts
index.ts
src/
domain/
entities/
user.ts
order.ts
value-objects/
email.ts
money.ts
repositories/
user.repository.ts # Interface only
order.repository.ts # Interface only
errors/
not-found.error.ts
validation.error.ts
application/
use-cases/
create-order.use-case.ts
get-user.use-case.ts
dto/
create-order.dto.ts
infrastructure/
persistence/
prisma-user.repository.ts # Implements domain interface
prisma-order.repository.ts
external/
stripe.adapter.ts
email.adapter.ts
presentation/
controllers/
orders.controller.ts
middleware/
auth.middleware.ts
error.middleware.ts
routes/
orders.routes.ts
config/
env.ts
index.ts
src/
modules/
auth/
index.ts # Public API (barrel export)
auth.service.ts
auth.repository.ts
auth.routes.ts
__tests__/
billing/
index.ts
billing.service.ts
billing.repository.ts
billing.routes.ts
__tests__/
orders/
index.ts
orders.service.ts
orders.repository.ts
orders.routes.ts
__tests__/
shared/
middleware/
utils/
config/
index.ts
Cross-module imports go through index.ts only. Direct imports of internal files across modules are a violation.
src/
auth.ts
orders.ts
billing.ts
db.ts
middleware.ts
types.ts
index.ts
Suitable only for serverless functions, small CLIs, or prototypes with < 5 files.
src/
app/
(auth)/
login/page.tsx
register/page.tsx
(dashboard)/
layout.tsx
page.tsx
orders/page.tsx
features/
auth/
hooks/use-auth.ts
components/login-form.tsx
api/auth.api.ts
orders/
hooks/use-orders.ts
components/order-list.tsx
api/orders.api.ts
components/
ui/
button.tsx
input.tsx
lib/
api-client.ts
utils.ts
store/
auth.store.ts
src/
features/
auth/
pages/login.tsx
hooks/use-auth.ts
components/login-form.tsx
api/auth.api.ts
orders/
pages/order-list.tsx
hooks/use-orders.ts
components/order-card.tsx
api/orders.api.ts
components/
ui/
layout/
lib/
api-client.ts
router.tsx
store/
App.tsx
main.tsx
src/
features/
auth/
screens/login-screen.tsx
hooks/use-auth.ts
components/login-form.tsx
api/auth.api.ts
orders/
screens/order-list-screen.tsx
hooks/use-orders.ts
components/order-card.tsx
api/orders.api.ts
components/
ui/
navigation/
root-navigator.tsx
auth-navigator.tsx
services/
storage.ts
notifications.ts
biometrics.ts
lib/
api-client.ts
store/
auth.store.ts
App.tsx
| Convention | File Naming | Class / Function | Exports |
|---|---|---|---|
| feature-based | {feature}.{layer}.ts (e.g., orders.service.ts) | OrdersService, createOrder | Named exports per file |
| layer-based | {entity}.{layer}.ts (e.g., order.controller.ts) | OrderController, OrderService | Named exports per file |
| domain-driven | {concept}.ts in layer directory | Order (entity), CreateOrderUseCase | Named exports per file |
| module-based | {module}/{layer}.ts | AuthService, BillingService | Barrel exports via index.ts |
| flat | {feature}.ts | createOrder, authenticateUser | Named exports per file |
| Pattern | Allowed Import Direction | Violation Example |
|---|---|---|
| clean-architecture | presentation -> application -> domain (never reverse) | Domain importing Express types |
| hexagonal | adapters -> ports -> domain (never reverse) | Domain importing Prisma client |
| layered | controllers -> services -> repositories (never reverse) | Repository importing controller |
| modular-monolith | Within module: any direction. Cross-module: public API (index.ts) only | Module A importing Module B's internal service |
| mvc | views -> controllers -> models (never reverse) | Model importing view logic |
| mvvm | view -> viewmodel -> model (never reverse) | Model importing view state |
Application-level error handling for structuring, propagating, and responding to errors. For security error mitigations (OWASP, rate limiting, input sanitization), see operational-patterns.
interface AppError {
code: string; // Machine-readable: "ORDER_NOT_FOUND", "VALIDATION_FAILED"
message: string; // Human-readable: "Order not found"
details?: unknown; // Validation errors array, debug context
requestId: string; // For support correlation
}
| Pattern | Strategy | Implementation |
|---|---|---|
| layered / mvc | Try-catch in controllers, centralized error middleware | Express app.use((err, req, res, next) => ...) catches all |
| clean-architecture | Domain errors as typed classes, use-case catches and maps to application errors | OrderNotFoundError extends DomainError, use-case returns Result<T, E> |
| hexagonal | Port defines error types, adapter catches infrastructure errors and maps to port errors | Database timeout -> RepositoryUnavailableError |
| event-driven | Dead letter queue for unprocessable events, structured error events | Failed event -> DLQ, log for replay. See architecture-methodology invariant on at-least-once processing. |
| serverless | Return structured error response, let platform handle retries | { statusCode: 500, body: JSON.stringify(appError) } |
| microservices | Each service returns domain error codes, API gateway maps to HTTP | gRPC status codes -> HTTP status codes at gateway |
| Domain Error Type | HTTP Status | When |
|---|---|---|
ValidationError | 400 | Input fails schema or business rule validation |
AuthenticationError | 401 | Missing, expired, or invalid credentials |
ForbiddenError | 403 | Valid auth but insufficient permissions |
NotFoundError | 404 | Entity does not exist or is not accessible |
ConflictError | 409 | Duplicate resource, idempotency key collision |
RateLimitError | 429 | Too many requests |
ExternalServiceError | 502 | Upstream dependency failed |
UnexpectedError | 500 | Unhandled exception (log full stack, return generic message) |
requestId), return sanitized AppError to the clientrequestId for cross-service correlation. See operational-patterns structured logging for format.architecture-methodology invariant on at-least-once processing with DLQ.| Pattern | Unit Tests | Integration Tests | E2E Tests | Contract Tests | Ratio |
|---|---|---|---|---|---|
| layered / mvc | Service logic, validators | API endpoints (supertest) | Critical user flows | N/A | 70 / 20 / 10 |
| clean-architecture | Use cases, domain entities | Adapters against real DB | Critical user flows | N/A | 60 / 30 / 10 |
| modular-monolith | Per-module service logic | Per-module API + cross-module | Critical cross-module flows | Between modules | 50 / 25 / 10 / 15 |
| microservices | Per-service logic | Intra-service with test DB | Cross-service critical paths | Between services (Pact) | 50 / 20 / 10 / 20 |
| event-driven | Event handlers, validators | Event processing pipeline | End-to-end event flows | Event schema validation | 50 / 20 / 10 / 20 |
| serverless | Function logic | With local emulator (SAM) | Deployed endpoint smoke tests | N/A | 60 / 30 / 10 |
| Layer | What to Test | What NOT to Test | Tooling |
|---|---|---|---|
| Domain / business logic | Rules, calculations, state transitions, edge cases | Framework code, database queries | Jest, Vitest, pytest |
| API endpoints | Request/response contracts, auth, validation, status codes | Internal service implementation | Supertest, httpx, Playwright API |
| Database | Migrations, complex queries, indexes, constraints | Simple CRUD operations | Testcontainers, in-memory SQLite |
| External integrations | Contract compliance, error handling for failures | Third-party uptime or correctness | MSW (mocks), Pact (contracts) |
| Frontend components | User interactions, conditional rendering, form validation | Styling, pixel-level layout | Testing Library, Storybook |
| E2E flows | Critical user journeys (signup, checkout, payment) | Every possible path | Playwright, Cypress |
Use these templates when populating the testing_strategy manifest field:
MVP / simple app:
Unit tests for business logic (Jest/Vitest). Integration tests for API endpoints (supertest). No E2E yet. Coverage target: 60%. Run in CI on every PR.
Multi-service production:
Unit tests for domain logic per service. Integration tests per service with test database. Contract tests between services (Pact). E2E for critical user flows (Playwright). Coverage target: 80%. Run in CI, E2E on staging deploy.
Event-driven / async:
Unit tests for event handlers and validators. Integration tests for event processing pipeline. Schema validation tests for event contracts. DLQ monitoring as implicit regression detection. Coverage target: 70%.
IF app has < 5 pages AND minimal shared state:
-> RECOMMEND: React useState + Context
-> REASONING: "No extra dependencies. Sufficient for simple apps. Upgrade when state gets complex."
-> DON'T USE: "Redux, Zustand — overkill at this scale"
ELSE IF primary state is server data (CRUD app, dashboard, admin panel):
-> RECOMMEND: React Query / TanStack Query (server state) + Zustand (client state)
-> REASONING: "Server cache is not client state. React Query handles caching, revalidation, loading states. Zustand for UI-only state (modals, sidebar)."
ELSE IF complex client-side state (collaborative editor, form builder, drag-and-drop):
-> RECOMMEND: Zustand or Redux Toolkit
-> REASONING: "Need predictable state updates, middleware, devtools, undo/redo support."
ELSE IF Next.js App Router with server components:
-> RECOMMEND: Server components for data fetching + Zustand for client state
-> REASONING: "Server components eliminate client state for read data. Zustand handles remaining interactive state."
ELSE IF Vue / Nuxt:
-> RECOMMEND: Pinia
-> REASONING: "Official Vue state management. Composable, typed, devtools integrated."
| Pattern | When to Use | Structure |
|---|---|---|
| Feature components | Feature-scoped, self-contained units | Feature folder with components/, hooks/, api/ |
| Presentational + Container | Clear data/UI separation needed | Container fetches data, presentational renders props |
| Compound components | Complex UI with shared state (Accordion, Tabs, Menu) | Parent provides context, children consume via hooks |
| Headless hooks | Reusable logic across different UIs | Logic in custom hooks, no rendered UI (e.g., useAuth, usePagination) |
| Pattern | When to Use | Implementation |
|---|---|---|
| Server Components (RSC) | Next.js App Router, data needed on initial render | async function Page() with direct fetch or DB query |
| Client-side fetching | Interactive data, user-triggered queries | React Query useQuery / useMutation |
| SSR + hydration | SEO-critical pages with interactivity | Next.js getServerSideProps or loader functions |
| Optimistic updates | Instant UI feedback (likes, toggles, status changes) | React Query onMutate — update cache before server confirms |
| Infinite scroll / pagination | Long lists, feeds, search results | React Query useInfiniteQuery with cursor-based pagination |
| Requirement | Strategy | Implementation |
|---|---|---|
| Read-only offline (view cached data) | Cache-first with background sync | MMKV / AsyncStorage + stale-while-revalidate fetch pattern |
| Write-while-offline (create/edit offline) | Local-first writes + sync queue | MMKV writes + background sync queue + server reconciliation on reconnect |
| Full offline capability | Local database + sync engine | WatermelonDB or Expo SQLite + custom sync protocol with conflict resolution |
Default recommendation: start with read-only offline caching. Add write-offline only when user research confirms the need.
| App Type | Pattern | Implementation |
|---|---|---|
| Tab-based (social, marketplace, dashboard) | Bottom tabs + stack per tab | Expo Router tabs or React Navigation bottom tabs |
| Flow-based (onboarding, checkout, multi-step forms) | Stack navigation with progress indicator | Stack navigator with step-aware header |
| Drawer-based (admin panels, settings-heavy apps) | Drawer + nested stacks | Drawer navigator with stack navigators per section |
| Deep-link driven (content apps, shared URLs) | URL-based file routing | Expo Router (file-based routing with deep link support) |
Create a services/ directory with platform-agnostic interfaces for capabilities that differ across platforms:
| Service | What It Abstracts | Example Implementations |
|---|---|---|
storage.ts | Secure key-value storage | Expo SecureStore, MMKV, AsyncStorage |
notifications.ts | Push notification registration and handling | Expo Notifications, Firebase Cloud Messaging |
biometrics.ts | Biometric authentication | Expo LocalAuthentication |
camera.ts | Camera and image capture | Expo Camera, react-native-image-picker |
Same principle as hexagonal architecture ports/adapters: feature code depends on the interface, not the platform implementation. Swap implementations without changing feature code.
Quick-reference table for selecting the full application_patterns block based on project profile:
| Project Profile | Architecture | Folder Convention | Error Handling | Testing Strategy |
|---|---|---|---|---|
| Simple CRUD API | layered | layer-based | Centralized error middleware + status code mapping | Unit + integration (70/30) |
| SaaS with complex domain | clean-architecture | domain-driven | Typed domain errors + use-case mapping + error middleware | Unit + integration + contract (60/30/10) |
| Modular product (pre-microservices) | modular-monolith | module-based | Per-module error codes + shared error middleware | Unit + integration per module + cross-module contract |
| Event-driven system | event-driven | feature-based | DLQ + structured error events + retry with backoff | Handler unit + schema validation + pipeline integration |
| Serverless API | serverless | flat | Structured error responses per function | Function unit + emulator integration (60/40) |
| Mobile app | mvvm | feature-based | Error boundaries + retry on network failure | Component unit + integration + E2E critical flows |
| Full-stack Next.js | layered | feature-based | Server action errors + error.tsx boundaries + API error middleware | RSC + API + Playwright E2E |
For security architecture decisions, see operational-patterns. For infrastructure and tooling decisions (cloud, database, auth, hosting), see prescriptive-decision-framework. For domain-specific depth (multi-tenant isolation, payment flows, AI orchestration), see product-type-detector templates. To evaluate your chosen patterns against quality standards, see well-architected.
Expert guidance for Next.js Cache Components and Partial Prerendering (PPR). **PROACTIVE ACTIVATION**: Use this skill automatically when working in Next.js projects that have `cacheComponents: true` in their next.config.ts/next.config.js. When this config is detected, proactively apply Cache Components patterns and best practices to all React Server Component implementations. **DETECTION**: At the start of a session in a Next.js project, check for `cacheComponents: true` in next.config. If enabled, this skill's patterns should guide all component authoring, data fetching, and caching decisions. **USE CASES**: Implementing 'use cache' directive, configuring cache lifetimes with cacheLife(), tagging cached data with cacheTag(), invalidating caches with updateTag()/revalidateTag(), optimizing static vs dynamic content boundaries, debugging cache issues, and reviewing Cache Component implementations.
Creating algorithmic art using p5.js with seeded randomness and interactive parameter exploration. Use this when users request creating art using code, generative art, algorithmic art, flow fields, or particle systems. Create original algorithmic art rather than copying existing artists' work to avoid copyright violations.