Code Writer Expert
Overview
Advanced expertise in writing clean, production-ready, idiomatic code across multiple languages and paradigms. Specialized in designing well-structured functions, classes, modules, and systems with a focus on correctness, readability, testability, performance, and security.
Use this skill with /codewriter-skill to get expert code writing, refactoring, design, or generation for any language or framework.
1. Code Writing Principles
- Clarity first: code is read far more than it is written — optimize for the reader
- Single Responsibility: each function/class does one thing and does it well
- DRY (Don't Repeat Yourself): extract duplication into named abstractions
- YAGNI: only write code that is needed now — no speculative generality
- Fail fast: validate inputs early, surface errors explicitly, never swallow exceptions
- Minimal surface area: expose only what callers need, keep internals private
- Immutability preference: prefer immutable data structures and pure functions
- Explicit over implicit: readable names, clear types, no magic numbers/strings
2. Naming Conventions
| Construct |
Convention |
Example |
| Variables |
descriptive nouns |
userCount, isLoading |
| Functions |
verb phrases |
fetchUser(), parseConfig() |
| Booleans |
is/has/can prefix |
isValid, hasPermission |
| Constants |
SCREAMING_SNAKE |
MAX_RETRIES, DEFAULT_TIMEOUT |
| Classes |
PascalCase nouns |
UserRepository, PaymentService |
| Interfaces |
PascalCase (no I prefix) |
Repository, EventEmitter |
| Files |
kebab-case or snake_case |
user-service.ts, auth_utils.py |
| Tests |
describe what + when + expected |
returns_error_when_email_is_empty |
3. Function Design
- Keep functions short: aim for < 20 lines; if longer, extract sub-functions
- Max 3 parameters: beyond that, use an options object/struct/dataclass
- No side effects in pure functions: separate computation from I/O
- Early returns: reduce nesting by returning/throwing early on invalid conditions
- Guard clauses: validate preconditions at the top before main logic
- One level of abstraction per function: don't mix high-level orchestration with low-level details
- Command-Query Separation: functions either do something OR return something, not both
- Avoid flag parameters: split into two functions instead of
doThing(flag: bool)
# Bad
def process(data, dry_run=False):
result = compute(data)
if not dry_run:
save(result)
return result
# Good
def compute_result(data): ...
def save_result(result): ...
4. Class & Module Design
- SOLID principles:
- S — Single Responsibility
- O — Open/Closed (extend via composition, not modification)
- L — Liskov Substitution (subtypes are substitutable)
- I — Interface Segregation (small, focused interfaces)
- D — Dependency Inversion (depend on abstractions)
- Composition over inheritance: prefer has-a over is-a relationships
- Dependency injection: pass dependencies in; don't instantiate them inside
- Factory functions/classes: encapsulate complex construction logic
- Repository pattern: abstract data access behind an interface
- Service layer: encapsulate business logic separately from controllers/routes
5. Error Handling
- Never swallow errors silently: always log or re-raise
- Use domain errors: define typed error classes (not just
Error("something failed"))
- Result types: use
Result<T, E> or Either patterns for expected failures
- Exception vs error return: exceptions for unexpected failures; return errors for expected ones
- Error messages: include what went wrong, where, and what the caller can do
// TypeScript Result pattern
type Result<T, E> = { ok: true; value: T } | { ok: false; error: E };
function parseId(raw: string): Result<number, string> {
const n = parseInt(raw, 10);
if (isNaN(n)) return { ok: false, error: `Invalid ID: "${raw}"` };
return { ok: true, value: n };
}
6. Language-Specific Best Practices
TypeScript / JavaScript
- Strict mode:
"strict": true in tsconfig
- Prefer
const → let → never var
- Optional chaining
?. and nullish coalescing ?? over explicit null checks
async/await over raw Promises and callback chains
- Use
unknown over any; narrow types explicitly
- Zod / Valibot for runtime validation at boundaries
Python
- Type annotations on all public functions/methods
- Dataclasses or Pydantic models over plain dicts
pathlib.Path over os.path string manipulation
- Context managers for resource management
__slots__ for performance-critical classes
logging module over print statements
Go
- Errors as values: always handle
err != nil
- Interfaces implicitly satisfied — keep them small (1-3 methods)
- Goroutines + channels for concurrency; use
context.Context for cancellation
defer for cleanup, not just error handling
- Table-driven tests with
t.Run
Rust
- Ownership and borrowing — prefer references over clones
Result<T, E> and Option<T> over panics at boundaries
thiserror for library errors, anyhow for application errors
- Iterators over manual loops
#[derive(Debug, Clone, PartialEq)] on data structs
Java / Kotlin
- Immutable data with
record (Java 16+) or data class (Kotlin)
- Builder pattern for objects with many optional fields
Optional<T> for nullable return values (Java); ? types (Kotlin)
- Stream API / sequences for collection processing
- Constructor injection for dependencies
7. Code Structure Patterns
Repository Pattern
interface UserRepository {
findById(id: string): Promise<User | null>;
save(user: User): Promise<void>;
delete(id: string): Promise<void>;
}
class PostgresUserRepository implements UserRepository { ... }
class InMemoryUserRepository implements UserRepository { ... } // for tests
Service Layer
class OrderService:
def __init__(self, orders: OrderRepository, payments: PaymentGateway):
self._orders = orders
self._payments = payments
def place_order(self, cart: Cart, payment: PaymentDetails) -> Order:
order = Order.from_cart(cart)
self._payments.charge(payment, order.total)
self._orders.save(order)
return order
Builder Pattern
class QueryBuilder {
private _table = "";
private _conditions: string[] = [];
private _limit?: number;
table(name: string) { this._table = name; return this; }
where(condition: string) { this._conditions.push(condition); return this; }
limit(n: number) { this._limit = n; return this; }
build(): string { ... }
}
8. Testing-Friendly Code
- Dependency injection: makes unit testing easy — swap real deps for mocks
- Pure functions: no mocking needed — input → output is deterministic
- Small functions: easy to test in isolation
- Avoid global state: global mutable state makes tests order-dependent
- Interfaces at boundaries: mock at interface boundaries, not concrete implementations
- Seams: design code to have natural injection points for test doubles
- Test naming:
<unit>_<scenario>_<expected> — e.g., login_with_wrong_password_returns_401
9. Performance-Aware Code Writing
- Avoid premature optimization — profile first, optimize after
- Prefer O(n) over O(n²) by using sets/maps for lookups
- Lazy evaluation: generators, iterators, streams over eagerly-loaded collections
- Batch DB queries instead of N+1 loops
- Cache pure function results with memoization
- Avoid allocations in hot paths (object pooling, pre-allocated buffers)
- Use streaming for large file/data processing
10. Security-Aware Code Writing
- Input validation: validate at every system boundary — never trust external data
- Parameterized queries: never concatenate user input into SQL
- Output encoding: escape HTML/JS output to prevent XSS
- Secrets in env vars: never hardcode tokens, passwords, or keys
- Least privilege: request only the permissions your code actually needs
- Safe deserialization: validate schemas before unmarshalling untrusted JSON/YAML
- Path traversal prevention: sanitize file paths; use allowlists
- Timing-safe comparisons: use constant-time comparison for secrets/tokens
11. Code Review Checklist
12. Refactoring Techniques
- Extract Function: pull repeated or complex logic into a named function
- Inline Function: remove unnecessary indirection when function body is self-evident
- Extract Variable: name complex expressions for readability
- Replace Magic Number: introduce a named constant
- Introduce Parameter Object: group related parameters into a struct/object
- Replace Conditional with Polymorphism: use strategy/factory instead of large if/switch
- Decompose Conditional: extract complex boolean logic into named predicate functions
- Replace Temp with Query: replace variables computed once with functions
Core Competency Summary
- Write clean, idiomatic, production-ready code in Python, TypeScript, Go, Rust, Java, and more
- Design functions, classes, and modules following SOLID principles
- Apply naming conventions, error handling, and guard clause patterns consistently
- Structure code for testability via dependency injection and pure functions
- Write security-aware code at every boundary
- Recognize and apply structural patterns: Repository, Service, Builder, Strategy
- Perform disciplined refactoring using established techniques
- Write code that passes review: correct, clear, tested, and performant
1---2name: codewriter-skill3description: Code Writer Expert4---5# Code Writer Expert67## Overview8Advanced expertise in writing clean, production-ready, idiomatic code across multiple languages and paradigms. Specialized in designing well-structured functions, classes, modules, and systems with a focus on correctness, readability, testability, performance, and security.910Use this skill with `/codewriter-skill` to get expert code writing, refactoring, design, or generation for any language or framework.1112---1314## 1. Code Writing Principles1516- **Clarity first**: code is read far more than it is written — optimize for the reader17- **Single Responsibility**: each function/class does one thing and does it well18- **DRY (Don't Repeat Yourself)**: extract duplication into named abstractions19- **YAGNI**: only write code that is needed now — no speculative generality20- **Fail fast**: validate inputs early, surface errors explicitly, never swallow exceptions21- **Minimal surface area**: expose only what callers need, keep internals private22- **Immutability preference**: prefer immutable data structures and pure functions23- **Explicit over implicit**: readable names, clear types, no magic numbers/strings2425---2627## 2. Naming Conventions2829| Construct | Convention | Example |30|---|---|---|31| Variables | descriptive nouns | `userCount`, `isLoading` |32| Functions | verb phrases | `fetchUser()`, `parseConfig()` |33| Booleans | is/has/can prefix | `isValid`, `hasPermission` |34| Constants | SCREAMING_SNAKE | `MAX_RETRIES`, `DEFAULT_TIMEOUT` |35| Classes | PascalCase nouns | `UserRepository`, `PaymentService` |36| Interfaces | PascalCase (no I prefix) | `Repository`, `EventEmitter` |37| Files | kebab-case or snake_case | `user-service.ts`, `auth_utils.py` |38| Tests | describe what + when + expected | `returns_error_when_email_is_empty` |3940---4142## 3. Function Design4344- **Keep functions short**: aim for < 20 lines; if longer, extract sub-functions45- **Max 3 parameters**: beyond that, use an options object/struct/dataclass46- **No side effects in pure functions**: separate computation from I/O47- **Early returns**: reduce nesting by returning/throwing early on invalid conditions48- **Guard clauses**: validate preconditions at the top before main logic49- **One level of abstraction per function**: don't mix high-level orchestration with low-level details50- **Command-Query Separation**: functions either do something OR return something, not both51- **Avoid flag parameters**: split into two functions instead of `doThing(flag: bool)`5253```python54# Bad55def process(data, dry_run=False):56 result = compute(data)57 if not dry_run:58 save(result)59 return result6061# Good62def compute_result(data): ...63def save_result(result): ...64```6566---6768## 4. Class & Module Design6970- **SOLID principles**:71 - *S* — Single Responsibility72 - *O* — Open/Closed (extend via composition, not modification)73 - *L* — Liskov Substitution (subtypes are substitutable)74 - *I* — Interface Segregation (small, focused interfaces)75 - *D* — Dependency Inversion (depend on abstractions)76- **Composition over inheritance**: prefer has-a over is-a relationships77- **Dependency injection**: pass dependencies in; don't instantiate them inside78- **Factory functions/classes**: encapsulate complex construction logic79- **Repository pattern**: abstract data access behind an interface80- **Service layer**: encapsulate business logic separately from controllers/routes8182---8384## 5. Error Handling8586- **Never swallow errors silently**: always log or re-raise87- **Use domain errors**: define typed error classes (not just `Error("something failed")`)88- **Result types**: use `Result<T, E>` or `Either` patterns for expected failures89- **Exception vs error return**: exceptions for unexpected failures; return errors for expected ones90- **Error messages**: include what went wrong, where, and what the caller can do9192```typescript93// TypeScript Result pattern94type Result<T, E> = { ok: true; value: T } | { ok: false; error: E };9596function parseId(raw: string): Result<number, string> {97 const n = parseInt(raw, 10);98 if (isNaN(n)) return { ok: false, error: `Invalid ID: "${raw}"` };99 return { ok: true, value: n };100}101```102103---104105## 6. Language-Specific Best Practices106107### TypeScript / JavaScript108- Strict mode: `"strict": true` in tsconfig109- Prefer `const` → `let` → never `var`110- Optional chaining `?.` and nullish coalescing `??` over explicit null checks111- `async/await` over raw Promises and callback chains112- Use `unknown` over `any`; narrow types explicitly113- Zod / Valibot for runtime validation at boundaries114115### Python116- Type annotations on all public functions/methods117- Dataclasses or Pydantic models over plain dicts118- `pathlib.Path` over `os.path` string manipulation119- Context managers for resource management120- `__slots__` for performance-critical classes121- `logging` module over print statements122123### Go124- Errors as values: always handle `err != nil`125- Interfaces implicitly satisfied — keep them small (1-3 methods)126- Goroutines + channels for concurrency; use `context.Context` for cancellation127- `defer` for cleanup, not just error handling128- Table-driven tests with `t.Run`129130### Rust131- Ownership and borrowing — prefer references over clones132- `Result<T, E>` and `Option<T>` over panics at boundaries133- `thiserror` for library errors, `anyhow` for application errors134- Iterators over manual loops135- `#[derive(Debug, Clone, PartialEq)]` on data structs136137### Java / Kotlin138- Immutable data with `record` (Java 16+) or `data class` (Kotlin)139- Builder pattern for objects with many optional fields140- `Optional<T>` for nullable return values (Java); `?` types (Kotlin)141- Stream API / sequences for collection processing142- Constructor injection for dependencies143144---145146## 7. Code Structure Patterns147148### Repository Pattern149```typescript150interface UserRepository {151 findById(id: string): Promise<User | null>;152 save(user: User): Promise<void>;153 delete(id: string): Promise<void>;154}155156class PostgresUserRepository implements UserRepository { ... }157class InMemoryUserRepository implements UserRepository { ... } // for tests158```159160### Service Layer161```python162class OrderService:163 def __init__(self, orders: OrderRepository, payments: PaymentGateway):164 self._orders = orders165 self._payments = payments166167 def place_order(self, cart: Cart, payment: PaymentDetails) -> Order:168 order = Order.from_cart(cart)169 self._payments.charge(payment, order.total)170 self._orders.save(order)171 return order172```173174### Builder Pattern175```typescript176class QueryBuilder {177 private _table = "";178 private _conditions: string[] = [];179 private _limit?: number;180181 table(name: string) { this._table = name; return this; }182 where(condition: string) { this._conditions.push(condition); return this; }183 limit(n: number) { this._limit = n; return this; }184 build(): string { ... }185}186```187188---189190## 8. Testing-Friendly Code191192- **Dependency injection**: makes unit testing easy — swap real deps for mocks193- **Pure functions**: no mocking needed — input → output is deterministic194- **Small functions**: easy to test in isolation195- **Avoid global state**: global mutable state makes tests order-dependent196- **Interfaces at boundaries**: mock at interface boundaries, not concrete implementations197- **Seams**: design code to have natural injection points for test doubles198- **Test naming**: `<unit>_<scenario>_<expected>` — e.g., `login_with_wrong_password_returns_401`199200---201202## 9. Performance-Aware Code Writing203204- Avoid premature optimization — profile first, optimize after205- Prefer O(n) over O(n²) by using sets/maps for lookups206- Lazy evaluation: generators, iterators, streams over eagerly-loaded collections207- Batch DB queries instead of N+1 loops208- Cache pure function results with memoization209- Avoid allocations in hot paths (object pooling, pre-allocated buffers)210- Use streaming for large file/data processing211212---213214## 10. Security-Aware Code Writing215216- **Input validation**: validate at every system boundary — never trust external data217- **Parameterized queries**: never concatenate user input into SQL218- **Output encoding**: escape HTML/JS output to prevent XSS219- **Secrets in env vars**: never hardcode tokens, passwords, or keys220- **Least privilege**: request only the permissions your code actually needs221- **Safe deserialization**: validate schemas before unmarshalling untrusted JSON/YAML222- **Path traversal prevention**: sanitize file paths; use allowlists223- **Timing-safe comparisons**: use constant-time comparison for secrets/tokens224225---226227## 11. Code Review Checklist228229- [ ] Does the code do what the ticket/spec says?230- [ ] Are edge cases handled (empty, null, large input, concurrency)?231- [ ] Are errors handled and surfaced appropriately?232- [ ] Are names descriptive and consistent with existing conventions?233- [ ] Is there unnecessary complexity or duplication?234- [ ] Are there tests, and do they cover the important paths?235- [ ] Are there any security issues (injection, exposure, auth bypass)?236- [ ] Does it perform acceptably under expected load?237- [ ] Are public APIs documented?238- [ ] Are there any TODO/FIXME that should be issues instead?239240---241242## 12. Refactoring Techniques243244- **Extract Function**: pull repeated or complex logic into a named function245- **Inline Function**: remove unnecessary indirection when function body is self-evident246- **Extract Variable**: name complex expressions for readability247- **Replace Magic Number**: introduce a named constant248- **Introduce Parameter Object**: group related parameters into a struct/object249- **Replace Conditional with Polymorphism**: use strategy/factory instead of large if/switch250- **Decompose Conditional**: extract complex boolean logic into named predicate functions251- **Replace Temp with Query**: replace variables computed once with functions252253---254255## Core Competency Summary256257- Write clean, idiomatic, production-ready code in Python, TypeScript, Go, Rust, Java, and more258- Design functions, classes, and modules following SOLID principles259- Apply naming conventions, error handling, and guard clause patterns consistently260- Structure code for testability via dependency injection and pure functions261- Write security-aware code at every boundary262- Recognize and apply structural patterns: Repository, Service, Builder, Strategy263- Perform disciplined refactoring using established techniques264- Write code that passes review: correct, clear, tested, and performant