This skill should be used when writing code in any opinionated framework's distinctive style. It applies when writing framework-based applications, creating models/controllers/views, or any framework code. Triggers on code generation, refactoring requests, code review, or when the user mentions framework conventions. Embodies the philosophy of embracing framework conventions, fighting complexity, and choosing simplicity over cleverness.
<essential_principles>
"The best code is the code you don't write. The second best is the code that's obviously correct."
Embrace the framework:
What to avoid (universal anti-patterns):
Development Philosophy:
Specify a number or describe your task and your framework (Django, Laravel, Next.js, etc.) </intake>
After reading relevant references, apply patterns to the user's code. </routing>
<framework_detection> Before providing guidance, identify the framework and load its specific conventions:
| Framework | Core Conventions | What to Embrace |
|---|---|---|
| Django | Fat models, thin views, ORM queries | Admin, class-based views, forms, signals |
| Laravel | Eloquent, Blade, Facades, Artisan | Resource controllers, form requests, events |
| Next.js | Server components, file routing, API routes | App router, server actions, middleware |
| Spring Boot | Auto-config, dependency injection, JPA | Starters, repositories, @Transactional |
| Phoenix | Contexts, Ecto, LiveView, channels | Generators, PubSub, presence |
| FastAPI | Pydantic, async, dependency injection | OpenAPI, background tasks, middleware |
| Rails | Fat models, thin controllers, conventions | Hotwire, concerns, Active* libraries |
| Remix | Loaders, actions, nested routes | Form handling, progressive enhancement |
| NestJS | Decorators, modules, providers | Guards, interceptors, pipes |
| </framework_detection> |
<quick_reference>
Actions: Domain verbs that describe what happens
card.close(), order.ship(), user.activate()card.setStatus('closed'), order.updateShipped(true)Predicates: Boolean queries derived from state
card.closed?, order.shipped?, user.active?card.isClosed, order.getIsShipped()Collections: Descriptive scope names
chronologically, alphabetically, recent, active, pendingsortByDate, filterActive, getRecentInstead of custom actions, create new resources:
Custom Action → RESTful Resource
POST /cards/:id/close → POST /cards/:id/closure
DELETE /cards/:id/close → DELETE /cards/:id/closure
POST /orders/:id/ship → POST /orders/:id/shipment
POST /users/:id/ban → POST /users/:id/ban
Instead of boolean flags, use related records or enums:
Boolean Flag → State Record/Enum
card.closed = true → card.closure (record exists)
order.shipped = true → order.shipment (record exists)
user.status = 'banned' → user.ban (record exists)
Query with joins/relations, not boolean comparisons:
- Cards with closures = closed cards
- Cards without closures = open cards
Before writing custom code, ask:
<reference_index>
All detailed patterns in references/:
| File | Topics |
|---|---|
| universal-patterns.md | REST mapping, state as data, naming, testing, frontend |
| anti-patterns.md | What to avoid, complexity traps, over-engineering signs |
| </reference_index> |
<success_criteria> Code follows framework conventions when:
The framework solves 90% of your problems elegantly. The remaining 10% often feels like it needs custom solutions, but usually:
When you truly need to go custom, document why and keep it isolated. </philosophy>