| name | coding-standards |
| description | Provides language-agnostic best practices and language-specific coding patterns for writing clean, maintainable code. |
Coding Standards
Language-agnostic best practices and language-specific patterns.
Extends: .claude/rules/essential-rules.md — this skill adds depth to the coding style, TypeScript, and testing sections defined there. For core rules (security, error handling, API design), see essential-rules.md.
Coding Style (from essential-rules)
Immutability
- Prefer
const over let, never var
- Immutable updates:
setState([...state, item])
Early Returns
function process(order: Order): Result {
if (!order) return { error: 'Order not found' };
if (!order.items.length) return { error: 'Empty order' };
return processPayment(order);
}
Naming
- Variables/functions: camelCase, descriptive
- Classes/types: PascalCase
- Constants: UPPER_SNAKE_CASE
- Booleans:
isX, hasX, shouldX
No Magic Numbers
const MAX_RETRY_ATTEMPTS = 3;
const SECONDS_IN_HOUR = 3600;
Comments
- Explain "why", not "what"
- Document complex business logic
- No obvious comments
Inferred Types
const count = 5;
const user = new User();
General Principles
SOLID Principles
- Single Responsibility: One class, one reason to change
- Open/Closed: Open for extension, closed for modification
- Liskov Substitution: Subtypes must be substitutable for base types
- Interface Segregation: Many specific interfaces > one general
- Dependency Inversion: Depend on abstractions, not concretions
DRY (Don't Repeat Yourself)
- Extract repeated logic into functions
- Use loops/maps instead of copy-paste
- Share common code via modules
KISS (Keep It Simple, Stupid)
- Simple solutions > clever solutions
- Optimize for readability first
- Premature optimization is the root of all evil
TypeScript/JavaScript
Modern JavaScript (ES6+)
const config = { api: 'https://api.example.com' };
let counter = 0;
items.map(item => item.name);
const { name, email } = user;
const [first, ...rest] = items;
const message = "Hello, " + user.name + "!";
const street = user?.address?.street;
const port = process.env.PORT ?? 3000;
async function fetchUser(id: string) {
const response = await fetch("/api/users/" + id);
return response.json();
}
TypeScript Best Practices
export function calculateTotal(items: Item[]): number {
return items.reduce((sum, item) => sum + item.price, 0);
}
interface User {
id: string;
name: string;
email: string;
}
type Status = 'pending' | 'active' | 'completed';
type ID = string | number;
function processData(data: unknown) {
if (typeof data === 'string') {
return data.toUpperCase();
}
}
function first<T>(arr: T[]): T | undefined {
return arr[0];
}
Python
PEP 8 Style
def calculate_total(items):
return sum(item.price for item in items)
class UserService:
pass
MAX_RETRY_ATTEMPTS = 3
def greet(name: str) -> str:
return f"Hello, {name}!"
squares = [x**2 for x in range(10)]
with open('file.txt', 'r') as f:
content = f.read()
message = f"User {user.name} logged in at {timestamp}"
Python Best Practices
from dataclasses import dataclass
@dataclass
class User:
id: str
name: str
email: str
from pathlib import Path
config_file = Path('config') / 'settings.json'
for index, item in enumerate(items):
print(f"{index}: {item}")
for name, score in zip(names, scores):
print(f"{name}: {score}")
try:
result = risky_operation()
except SpecificError as e:
logger.error(f"Operation failed: {e}")
raise
Go
Go Idioms
result, err := doSomething()
if err != nil {
return nil, fmt.Errorf("doSomething failed: %w", err)
}
func processFile(filename string) error {
f, err := os.Open(filename)
if err != nil {
return err
}
defer f.Close()
return nil
}
type Reader interface {
Read(p []byte) (n int, err error)
}
type Stringer interface {
String() string
}
func fetchData(ctx context.Context, url string) ([]byte, error) {
req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
}
Rust
Rust Patterns
fn divide(a: i32, b: i32) -> Result<i32, String> {
if b == 0 {
return Err("Division by zero".to_string());
}
Ok(a / b)
}
fn find_user(id: &str) -> Option<User> {
}
match result {
Ok(value) => println!("Success: {}", value),
Err(e) => eprintln!("Error: {}", e),
}
fn process(data: &str) {
}
let sum: i32 = numbers
.iter()
.filter(|&&x| x > 0)
.map(|&x| x * 2)
.sum();
Common Patterns
Error Handling
type Result<T, E = Error> =
| { ok: true; value: T }
| { ok: false; error: E };
function parseJSON(text: string): Result<any> {
try {
return { ok: true, value: JSON.parse(text) };
} catch (error) {
return { ok: false, error: error as Error };
}
}
const result = parseJSON(text);
if (result.ok) {
console.log(result.value);
} else {
console.error(result.error);
}
Builder Pattern
class QueryBuilder {
private query: string[] = [];
select(...fields: string[]) {
this.query.push("SELECT " + fields.join(', '));
return this;
}
from(table: string) {
this.query.push("FROM " + table);
return this;
}
where(condition: string) {
this.query.push("WHERE " + condition);
return this;
}
build() {
return this.query.join(' ');
}
}
const sql = new QueryBuilder()
.select('name', 'email')
.from('users')
.where('active = true')
.build();
Factory Pattern
interface Animal {
speak(): string;
}
class Dog implements Animal {
speak() { return 'Woof!'; }
}
class Cat implements Animal {
speak() { return 'Meow!'; }
}
class AnimalFactory {
static create(type: string): Animal {
switch (type) {
case 'dog': return new Dog();
case 'cat': return new Cat();
default: throw new Error('Unknown animal type');
}
}
}
Repository Pattern
interface Repository<T> {
findById(id: string): Promise<T | null>;
findAll(): Promise<T[]>;
save(entity: T): Promise<T>;
delete(id: string): Promise<void>;
}
class UserRepository implements Repository<User> {
constructor(private db: Database) {}
async findById(id: string): Promise<User | null> {
return this.db.query('SELECT * FROM users WHERE id = $1', [id]);
}
async findAll(): Promise<User[]> {
return this.db.query('SELECT * FROM users');
}
async save(user: User): Promise<User> {
return user;
}
async delete(id: string): Promise<void> {
await this.db.query('DELETE FROM users WHERE id = $1', [id]);
}
}
Code Review Checklist
Resources