| name | universal-patterns |
| description | Use when implementing language-agnostic patterns like layered architecture, dependency injection, error handling, or code organization principles across any technology stack. |
| user-invocable | false |
Universal Development Patterns
Overview
Language-agnostic development patterns and best practices applicable across all technology stacks.
The deep catalog lives next door โ read it for any real design decision
This file is the quick reference. It carries enough to keep everyday code honest. It is
deliberately shallow on architecture, and it contains none of the 22 GoF design
patterns.
For anything beyond a reminder โ choosing a style, comparing two, or picking a design
pattern โ read the architecture skill's index, then follow where it routes you:
<dev-plugin-root>/skills/architecture/SKILL.md
Locate it relative to this plugin's root, which covers both the installed-cache and
local-source layouts:
ls "${CLAUDE_PLUGIN_ROOT}/skills/architecture/SKILL.md" 2>/dev/null \
|| ls "$(dirname "$(dirname "$(pwd)")")"/plugins/dev/skills/architecture/SKILL.md 2>/dev/null
That index routes in two steps: altitude first (is this about system shape or class
collaboration), then the specific file. What it covers, none of which is below:
| Tier | Files | Contents |
|---|
| Architectural styles | references/styles/*.md | layered, hexagonal (ports and adapters), clean, modular monolith, microservices, event-driven, CQRS + event sourcing |
| GoF categories | references/{creational,structural,behavioral}.md | the shared framing for each family |
| GoF patterns | references/patterns/*.md | all 22, with TypeScript, trade-offs, and when not to use each |
| Selection | references/selection.md | how to choose, overuse smells, and where TypeScript already gives you the pattern free |
Do not answer an architecture question from the summaries below when the deep file
exists. The summaries omit the trade-offs and the failure modes, which are the parts that
decide whether the choice is right.
Architecture Patterns (summary โ see the architecture skill for the real treatment)
Layered Architecture
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Presentation Layer โ UI, API handlers, CLI
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ Application Layer โ Use cases, services
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ Domain Layer โ Business logic, entities
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ Infrastructure Layer โ DB, cache, external APIs
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
When to Use: Most applications benefit from clear separation of concerns.
Clean Architecture
โโโโโโโโโโโโโโโโโโโ
โ Frameworks โ (outermost)
โ & Drivers โ
โโโโโดโโโโโโโโโโโโโโโโโโดโโโโ
โ Interface Adapters โ
โ (Controllers, Gateways)โ
โโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโดโโโโ
โ Application Business โ
โ Rules (Use Cases) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Enterprise Business Rules โ (innermost)
โ (Entities) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Dependency Rule: Dependencies point inward. Inner layers don't know about outer layers.
Component-Based Architecture (Frontend)
src/
โโโ components/
โ โโโ common/ # Shared UI components
โ โโโ layout/ # Layout components
โ โโโ features/ # Feature-specific components
โโโ hooks/ # Custom hooks
โโโ stores/ # State management
โโโ services/ # API services
โโโ utils/ # Utilities
Code Organization Principles
Single Responsibility
Each module/function should do ONE thing well.
// BAD: Multiple responsibilities
function processUser(user) {
validateUser(user);
saveToDatabase(user);
sendEmail(user);
logAnalytics(user);
}
// GOOD: Single responsibility
function validateUser(user) { /* validation only */ }
function saveUser(user) { /* persistence only */ }
function notifyUser(user) { /* notification only */ }
Dependency Injection
Inject dependencies rather than creating them internally.
// BAD: Hard dependency
class UserService {
constructor() {
this.db = new Database(); // Hard-coded
}
}
// GOOD: Injected dependency
class UserService {
constructor(db) {
this.db = db; // Injected
}
}
Interface Segregation
Prefer many specific interfaces over one general interface.
// BAD: Fat interface
interface Worker {
work();
eat();
sleep();
}
// GOOD: Segregated interfaces
interface Workable { work(); }
interface Eatable { eat(); }
interface Sleepable { sleep(); }
Error Handling Patterns
Fail Fast
Validate inputs early and fail immediately on invalid data.
function processOrder(order) {
// Validate early
if (!order) throw new Error('Order required');
if (!order.items?.length) throw new Error('Order must have items');
if (!order.customerId) throw new Error('Customer ID required');
// Process only after validation passes
return executeOrder(order);
}
Error Boundaries
Contain errors at appropriate boundaries.
// API boundary - catch and format errors
async function apiHandler(req, res) {
try {
const result = await processRequest(req);
res.json({ success: true, data: result });
} catch (error) {
res.status(error.statusCode || 500).json({
success: false,
error: error.message
});
}
}
Result Types (Where Supported)
Use Result/Either types instead of exceptions for expected failures.
type Result<T, E> = { ok: true; value: T } | { ok: false; error: E };
function parseConfig(input: string): Result<Config, ParseError> {
try {
return { ok: true, value: JSON.parse(input) };
} catch (e) {
return { ok: false, error: new ParseError(e.message) };
}
}
Data Flow Patterns
Unidirectional Data Flow
Data flows in one direction through the application.
Action โ Dispatcher โ Store โ View โ Action
Event-Driven Architecture
Decouple components through events.
// Publisher
eventBus.emit('user.created', { userId: '123' });
// Subscriber
eventBus.on('user.created', async (event) => {
await sendWelcomeEmail(event.userId);
});
Command Query Separation (CQS)
Separate commands (mutations) from queries (reads).
// Query - returns data, no side effects
function getUser(id) { return db.users.find(id); }
// Command - mutates data, returns void/status
function updateUser(id, data) { db.users.update(id, data); }
Naming Conventions
Functions
| Type | Convention | Examples |
|---|
| Actions | verb + noun | createUser, deleteOrder, validateInput |
| Queries | get/find/is/has + noun | getUser, findOrders, isValid, hasPermission |
| Handlers | handle + event | handleClick, handleSubmit, handleError |
| Callbacks | on + event | onSuccess, onError, onChange |
Variables
| Type | Convention | Examples |
|---|
| Booleans | is/has/can/should | isActive, hasAccess, canEdit, shouldRefresh |
| Collections | plural | users, orders, items |
| Counts | count/num/total | userCount, numItems, totalPrice |
Files
| Type | Convention | Examples |
|---|
| Components | PascalCase | UserProfile.tsx, OrderList.vue |
| Utilities | camelCase/kebab | formatDate.ts, string-utils.ts |
| Constants | SCREAMING_SNAKE | API_ENDPOINTS.ts, ERROR_CODES.ts |
| Tests | name.test/spec | user.test.ts, order.spec.ts |
Code Quality Checklist
Before committing code, verify:
Anti-Patterns to Avoid
God Objects
Objects that know too much or do too much. Split into focused components.
Premature Optimization
Don't optimize before measuring. Write clear code first, optimize proven bottlenecks.
Stringly Typed
Using strings where enums/types would be safer. Use type systems.
Copy-Paste Programming
Duplicating code instead of abstracting. But: prefer duplication over wrong abstraction.
Boolean Parameters
Functions with boolean flags that change behavior. Split into explicit functions.
// BAD
function process(data, isAdmin) { /* behaves differently based on flag */ }
// GOOD
function processUserData(data) { /* user logic */ }
function processAdminData(data) { /* admin logic */ }
Performance Principles
- Measure First: Profile before optimizing
- Lazy Loading: Load resources only when needed
- Caching: Cache expensive computations and API calls
- Pagination: Don't load everything at once
- Batch Operations: Combine multiple operations when possible
- Async/Parallel: Use concurrency for independent operations
Security Principles
- Input Validation: Never trust user input
- Output Encoding: Encode data for its context (HTML, SQL, etc.)
- Least Privilege: Request minimum permissions needed
- Defense in Depth: Multiple layers of security
- Fail Secure: Default to denying access on errors
- Secrets Management: Never hardcode secrets, use environment variables
Language-Specific Knowledge Bases (cross-plugin)
These universal patterns are language-agnostic. When the task targets a specific
language, a companion plugin may ship a curated, production-grade knowledge base
for it. Prefer that knowledge over generic patterns when it exists.
Go โ the go plugin's knowledge base
If the task involves Go, check whether the go@magus plugin is installed alongside
this one and read its knowledge base. It is bundled as plain files next to the dev
plugin, so locate it relative to this plugin's root (${CLAUDE_PLUGIN_ROOT}), which
covers both install topologies:
ls "${CLAUDE_PLUGIN_ROOT}/../go/knowledge/roles" 2>/dev/null \
|| ls "${CLAUDE_PLUGIN_ROOT}"/../../go/*/knowledge/roles 2>/dev/null
If found, read the files matching your role and task before writing Go:
knowledge/roles/<role>/best-practices.md โ role guidance (developer,
architect, tester, code-reviewer)
knowledge/roles/<role>/implementation-references.md โ index into the references
knowledge/references/*.md โ production-code patterns (error handling, concurrency,
interface design, context usage, testing, http-api, etc.)
knowledge/uber-go-style-guide.md, knowledge/100-go-mistakes.md,
knowledge/go-proverbs.md โ style and pitfalls
Apply this Go knowledge in preference to the generic patterns above. The role names
map to dev agents: developerโdev:developer, architectโdev:architect,
testerโdev:test-architect, code-reviewerโdev:reviewer.
If NOT found and the task is Go-heavy, tell the user once, then proceed with the
generic patterns:
๐ก A curated Go knowledge base (Uber style guide, 100 Go Mistakes, production
patterns) is available in the go plugin. Install it for higher-quality Go work:
/plugin install go@magus
Do not block on this โ it is an enhancement, not a requirement.
Universal patterns applicable to all technology stacks