
Clean Code
- 6 installs
- 404 repo stars
- Updated August 5, 2026
- aiskillstore/marketplace
clean-code is a Claude Code skill that applies DRY, KISS, and YAGNI clean-code principles to TypeScript-first functional development.
About
clean-code is a Claude Code skill that applies clean-code principles for TypeScript-first, functional development. It gives concrete before-and-after examples for DRY, KISS, and YAGNI plus a checklist for naming and small single-purpose functions. A developer uses it when writing or reviewing TypeScript to catch duplication, over-engineering, and unclear naming.
- Clean-code principles adapted for TypeScript-first functional development
- Concrete before/after refactors for DRY, KISS, and YAGNI
- A clean-code checklist covering naming and single-purpose functions
Clean Code by the numbers
- 6 all-time installs (skills.sh)
- Ranked #870 of 1,352 Code Review & Quality skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
clean-code capabilities & compatibility
- Capabilities
- code review · refactoring · code quality audit · naming guidance
- Use cases
- code review · refactoring
What clean-code says it does
Clean code principles adapted for TypeScript-first, functional development.
Every piece of knowledge should have a single, unambiguous representation.
npx skills add https://github.com/aiskillstore/marketplace --skill clean-codeAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 6 |
|---|---|
| repo stars | ★ 404 |
| Last updated | August 5, 2026 |
| Repository | aiskillstore/marketplace ↗ |
What it does
Apply DRY, KISS, and YAGNI clean-code principles when writing or reviewing TypeScript code.
Who is it for?
Developers writing or reviewing TypeScript who want DRY/KISS/YAGNI refactoring guidance
Skip if: Language-specific style outside TypeScript or full architectural design
When should I use this skill?
Writing or reviewing TypeScript code and looking to remove duplication, over-engineering, or unclear naming
By the numbers
- covers 3 core principles (DRY, KISS, YAGNI)
- includes a clean-code checklist for naming and functions
Files
Clean Code Skill for Node.js/TypeScript
Overview
Clean code principles adapted for TypeScript-first, functional development.
DRY - Don't Repeat Yourself
Principle
Every piece of knowledge should have a single, unambiguous representation.
Violations
// Bad: Duplicated validation logic
const validateUserEmail = (email: string) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
const isValidEmail = (email: string) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
// Bad: Magic numbers everywhere
if (password.length < 8) { ... }
if (retries > 3) { ... }
if (timeout > 30000) { ... }Correct
// Good: Single source of truth
const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
const validateEmail = (email: string): boolean => EMAIL_REGEX.test(email);
// Good: Named constants
const PASSWORD_MIN_LENGTH = 8;
const MAX_RETRIES = 3;
const REQUEST_TIMEOUT_MS = 30_000;
if (password.length < PASSWORD_MIN_LENGTH) { ... }
if (retries > MAX_RETRIES) { ... }
if (timeout > REQUEST_TIMEOUT_MS) { ... }Extract Shared Logic
// Before: Duplicated fetch logic
const fetchUsers = async () => {
const response = await fetch('/api/users');
if (!response.ok) throw new Error('Failed to fetch');
return response.json();
};
const fetchOrders = async () => {
const response = await fetch('/api/orders');
if (!response.ok) throw new Error('Failed to fetch');
return response.json();
};
// After: Extracted common logic
const fetchJson = async <T>(url: string): Promise<T> => {
const response = await fetch(url);
if (!response.ok) throw new Error(`Failed to fetch: ${url}`);
return response.json();
};
const fetchUsers = () => fetchJson<User[]>('/api/users');
const fetchOrders = () => fetchJson<Order[]>('/api/orders');KISS - Keep It Simple
Principle
Prefer simple solutions over clever ones. Complexity should be justified.
Violations
// Bad: Overly clever one-liner
const transform = (arr: number[]) =>
arr.reduce((acc, val, idx) => ({ ...acc, [idx]: val ** 2 }), {});
// Bad: Premature abstraction
interface DataTransformer<T, U> {
transform(input: T): U;
validate(input: T): boolean;
normalize(input: T): T;
}
class UserNameTransformer implements DataTransformer<User, string> {
// 50 lines for a simple name extraction...
}Correct
// Good: Clear and readable
const squareValues = (arr: number[]): Record<number, number> => {
const result: Record<number, number> = {};
for (let i = 0; i < arr.length; i++) {
result[i] = arr[i] ** 2;
}
return result;
};
// Good: Simple function for simple task
const getUserFullName = (user: User): string =>
`${user.firstName} ${user.lastName}`;Simplify Conditionals
// Before: Complex nested conditions
const getDiscount = (user: User, order: Order) => {
if (user.isPremium) {
if (order.total > 100) {
if (order.items.length > 5) {
return 0.25;
}
return 0.20;
}
return 0.15;
} else {
if (order.total > 200) {
return 0.10;
}
return 0;
}
};
// After: Early returns, clear conditions
const getDiscount = (user: User, order: Order): number => {
if (!user.isPremium) {
return order.total > 200 ? 0.10 : 0;
}
if (order.total <= 100) return 0.15;
if (order.items.length > 5) return 0.25;
return 0.20;
};YAGNI - You Aren't Gonna Need It
Principle
Don't build features until they're actually needed.
Violations
// Bad: Configurable everything "just in case"
interface UserServiceConfig {
maxRetries: number;
retryDelay: number;
cacheEnabled: boolean;
cacheTTL: number;
logLevel: 'debug' | 'info' | 'warn' | 'error';
metricsEnabled: boolean;
circuitBreakerThreshold: number;
// ... 20 more options never used
}
// Bad: Premature generalization
const createGenericCRUDService = <T extends Entity>(
repository: Repository<T>,
validator: Validator<T>,
transformer: Transformer<T>,
hooks: Hooks<T>,
cache: Cache<T>,
) => { ... };
// Used only for User entityCorrect
// Good: Build what you need now
const createUserService = (db: Database) => ({
findById: (id: string) => db.users.findFirst({ where: { id } }),
create: (data: CreateUserData) => db.users.create({ data }),
});
// Good: Add features when needed
// v1: Simple implementation
const fetchData = async (url: string) => {
const response = await fetch(url);
return response.json();
};
// v2: Add retry only when you actually need it
const fetchDataWithRetry = async (url: string, retries = 3) => {
for (let i = 0; i < retries; i++) {
try {
const response = await fetch(url);
return response.json();
} catch (error) {
if (i === retries - 1) throw error;
}
}
};Clean Code Checklist
Naming
// Bad
const d = new Date();
const u = getUser();
const doStuff = () => { ... };
// Good
const createdAt = new Date();
const currentUser = getUser();
const sendNotification = () => { ... };Functions
// Bad: Does multiple things
const processUser = async (user: User) => {
// Validate
// Transform
// Save
// Notify
// Log
// 100 lines...
};
// Good: Single purpose, small
const validateUser = (user: User): Result<User, ValidationError> => { ... };
const saveUser = (db: Database) => (user: User): Promise<User> => { ... };
const notifyUser = (notifier: Notifier) => (user: User): Promise<void> => { ... };Error Handling
// Bad: Swallowing errors
try {
await riskyOperation();
} catch (e) {
console.log('error');
}
// Bad: Generic error
throw new Error('Something went wrong');
// Good: Typed errors with context
type OperationError =
| { code: 'VALIDATION_FAILED'; field: string; message: string }
| { code: 'NOT_FOUND'; resourceId: string }
| { code: 'PERMISSION_DENIED'; userId: string; action: string };
const performOperation = (): Result<Data, OperationError> => {
if (!isValid(input)) {
return Result.fail({
code: 'VALIDATION_FAILED',
field: 'email',
message: 'Invalid email format',
});
}
// ...
};Comments
// Bad: Obvious comments
// Increment counter
counter++;
// Add user to array
users.push(user);
// Good: Explain WHY, not WHAT
// Skip validation for admin users per security policy SEC-123
if (user.role === 'admin') return true;
// Using insertion sort because array is nearly sorted (< 10 elements typically)
insertionSort(items);Formatting
// Bad: Inconsistent, hard to scan
const config={debug:true,timeout:1000,retries:3};
// Good: Consistent, easy to scan
const config = {
debug: true,
timeout: 1000,
retries: 3,
};Code Organization
Layered Structure
src/
api/ # HTTP layer (Express/Fastify handlers)
routes/
middleware/
services/ # Business logic (pure when possible)
repositories/ # Data access
types/ # Shared type definitions
utils/ # Pure utility functionsPure Core, Impure Shell
// Pure core - easy to test
const calculateOrderTotal = (items: OrderItem[]): number =>
items.reduce((sum, item) => sum + item.price * item.quantity, 0);
const validateOrder = (order: Order): Result<Order, ValidationError> => {
if (!order.items.length) return Result.fail({ code: 'EMPTY_ORDER' });
return Result.ok(order);
};
// Impure shell - handles I/O
const createOrderHandler = (deps: Dependencies) =>
async (req: Request, res: Response) => {
const validation = validateOrder(req.body);
if (validation.isFailure) {
return res.status(400).json(validation.error);
}
const total = calculateOrderTotal(validation.value.items);
const saved = await deps.orderRepo.save({ ...validation.value, total });
return res.status(201).json(saved);
};Clean Code Reference
Naming Conventions
Variables and Constants
// Booleans: use is/has/can/should prefix
const isActive = true;
const hasPermission = user.role === 'admin';
const canEdit = hasPermission && isActive;
const shouldNotify = user.preferences.notifications;
// Collections: use plural nouns
const users: User[] = [];
const orderItems: OrderItem[] = [];
const userIdToOrderMap: Map<string, Order> = new Map();
// Functions: use verb + noun
const fetchUsers = () => { ... };
const calculateTotal = (items: Item[]) => { ... };
const validateEmail = (email: string) => { ... };
// Constants: SCREAMING_SNAKE_CASE for true constants
const MAX_RETRY_ATTEMPTS = 3;
const API_BASE_URL = 'https://api.example.com';
const DEFAULT_TIMEOUT_MS = 5000;Functions
// Descriptive names that indicate behavior
const sendWelcomeEmail = (user: User) => { ... };
const parseConfigFromEnv = () => { ... };
const convertCelsiusToFahrenheit = (celsius: number) => { ... };
// Predicate functions: start with is/has/can
const isValidEmail = (email: string): boolean => { ... };
const hasRequiredPermissions = (user: User): boolean => { ... };
const canAccessResource = (user: User, resource: Resource): boolean => { ... };Types and Interfaces
// Types: PascalCase, descriptive
type UserId = string;
type EmailAddress = string;
type OrderStatus = 'pending' | 'processing' | 'completed' | 'cancelled';
// Interfaces: describe shape, often with -able, -like suffixes for behaviors
interface Serializable {
serialize(): string;
}
interface UserLike {
id: string;
email: string;
}
// Result types: clearly indicate success/failure
type CreateUserResult = Result<User, CreateUserError>;
type FetchOrdersResult = Result<Order[], FetchError>;Function Design
Single Level of Abstraction
// Bad: Mixed abstraction levels
const processOrder = async (order: Order) => {
// High level
const validated = validateOrder(order);
// Low level implementation detail
for (const item of order.items) {
if (item.quantity <= 0) {
throw new Error('Invalid quantity');
}
}
// High level again
await saveOrder(validated);
};
// Good: Consistent abstraction
const processOrder = async (order: Order) => {
const validated = validateOrder(order);
const priced = calculatePricing(validated);
const saved = await saveOrder(priced);
await notifyUser(saved);
return saved;
};Guard Clauses
// Bad: Deep nesting
const processUser = (user: User | null) => {
if (user) {
if (user.isActive) {
if (user.hasVerifiedEmail) {
// Do the actual work
return doWork(user);
} else {
throw new Error('Email not verified');
}
} else {
throw new Error('User inactive');
}
} else {
throw new Error('User required');
}
};
// Good: Guard clauses
const processUser = (user: User | null) => {
if (!user) throw new Error('User required');
if (!user.isActive) throw new Error('User inactive');
if (!user.hasVerifiedEmail) throw new Error('Email not verified');
return doWork(user);
};Small Functions
// Bad: 100+ line function
const handleRequest = async (req: Request) => {
// 100 lines of mixed concerns...
};
// Good: Composed small functions
const handleRequest = async (req: Request) => {
const input = parseInput(req);
const validated = validateInput(input);
const processed = await processInput(validated);
return formatResponse(processed);
};
const parseInput = (req: Request): RawInput => { /* 5-10 lines */ };
const validateInput = (input: RawInput): Result<ValidInput, Error> => { /* 5-10 lines */ };
const processInput = async (input: ValidInput): Promise<Output> => { /* 5-10 lines */ };
const formatResponse = (output: Output): Response => { /* 5-10 lines */ };Error Handling
Typed Errors
// Define error types
type ValidationError = {
code: 'VALIDATION_ERROR';
field: string;
message: string;
};
type NotFoundError = {
code: 'NOT_FOUND';
resource: string;
id: string;
};
type AuthError = {
code: 'UNAUTHORIZED' | 'FORBIDDEN';
reason: string;
};
type AppError = ValidationError | NotFoundError | AuthError;
// Handle exhaustively
const handleError = (error: AppError): Response => {
switch (error.code) {
case 'VALIDATION_ERROR':
return { status: 400, body: { field: error.field, message: error.message } };
case 'NOT_FOUND':
return { status: 404, body: { message: `${error.resource} not found` } };
case 'UNAUTHORIZED':
case 'FORBIDDEN':
return { status: error.code === 'UNAUTHORIZED' ? 401 : 403, body: { reason: error.reason } };
}
};Result Pattern
type Result<T, E> =
| { isSuccess: true; isFailure: false; value: T }
| { isSuccess: false; isFailure: true; error: E };
const Result = {
ok: <T>(value: T): Result<T, never> => ({
isSuccess: true,
isFailure: false,
value,
}),
fail: <E>(error: E): Result<never, E> => ({
isSuccess: false,
isFailure: true,
error,
}),
};
// Usage
const divide = (a: number, b: number): Result<number, 'DIVISION_BY_ZERO'> => {
if (b === 0) return Result.fail('DIVISION_BY_ZERO');
return Result.ok(a / b);
};
const result = divide(10, 2);
if (result.isSuccess) {
console.log(result.value); // 5
} else {
console.log(result.error); // 'DIVISION_BY_ZERO'
}Async Error Handling
// Good: Explicit error handling with Result
const fetchUser = async (id: string): Promise<Result<User, FetchError>> => {
try {
const response = await fetch(`/api/users/${id}`);
if (!response.ok) {
return Result.fail({ code: 'HTTP_ERROR', status: response.status });
}
const data = await response.json();
return Result.ok(data);
} catch (error) {
return Result.fail({ code: 'NETWORK_ERROR', message: String(error) });
}
};
// Chain results
const processUser = async (id: string): Promise<Result<ProcessedUser, AppError>> => {
const userResult = await fetchUser(id);
if (userResult.isFailure) return userResult;
const validationResult = validateUser(userResult.value);
if (validationResult.isFailure) return validationResult;
return Result.ok(transform(validationResult.value));
};Immutability
// Bad: Mutation
const addItem = (cart: Cart, item: Item) => {
cart.items.push(item); // Mutates original
cart.total += item.price;
return cart;
};
// Good: Immutable update
const addItem = (cart: Cart, item: Item): Cart => ({
...cart,
items: [...cart.items, item],
total: cart.total + item.price,
});
// Good: Using immer for complex updates
import { produce } from 'immer';
const addItem = (cart: Cart, item: Item): Cart =>
produce(cart, (draft) => {
draft.items.push(item);
draft.total += item.price;
});Dependency Injection
// Bad: Hardcoded dependencies
import { db } from './database';
import { logger } from './logger';
const createUser = async (data: CreateUserData) => {
logger.info('Creating user');
return db.users.create({ data });
};
// Good: Injected dependencies
type Dependencies = {
db: Database;
logger: Logger;
};
const createUserService = (deps: Dependencies) => ({
create: async (data: CreateUserData) => {
deps.logger.info('Creating user');
return deps.db.users.create({ data });
},
});
// Wire up at composition root
const userService = createUserService({
db: prismaClient,
logger: pinoLogger,
});Async/Await Best Practices
// Bad: Mixing async patterns
const fetchData = () => {
return fetch('/api/data')
.then((res) => res.json())
.then((data) => {
return new Promise((resolve) => {
setTimeout(() => resolve(data), 100);
});
});
};
// Good: Consistent async/await
const fetchData = async () => {
const response = await fetch('/api/data');
const data = await response.json();
await delay(100);
return data;
};
// Good: Parallel execution when possible
const fetchAllData = async () => {
const [users, orders, products] = await Promise.all([
fetchUsers(),
fetchOrders(),
fetchProducts(),
]);
return { users, orders, products };
};
// Good: Error handling
const fetchWithFallback = async <T>(
primary: () => Promise<T>,
fallback: () => Promise<T>
): Promise<T> => {
try {
return await primary();
} catch {
return await fallback();
}
};Code Organization
// File structure: group by feature
src/
users/
user.types.ts // Types
user.service.ts // Business logic
user.repository.ts // Data access
user.handler.ts // HTTP layer
user.test.ts // Tests
orders/
order.types.ts
order.service.ts
...
// Barrel exports for clean imports
// users/index.ts
export { createUserService } from './user.service';
export type { User, CreateUserData } from './user.types';
// Usage
import { createUserService, User } from './users';{
"schema_version": "2.0",
"meta": {
"generated_at": "2026-01-17T05:34:28.895Z",
"slug": "doubleslashse-clean-code",
"source_url": "https://github.com/DoubleslashSE/claude-workflows/tree/main/Plugins/dotnet-tdd/skills/clean-code",
"source_ref": "main",
"model": "claude",
"analysis_version": "3.0.0",
"source_type": "community",
"content_hash": "52bb09c0697f1576e82c96ddbf64de68f8600c125159310be2fd2cad1442bee8",
"tree_hash": "36b63eab617e9f61b3f18693afbebd3db827797b7b464c215b577920f3d48d6b"
},
"skill": {
"name": "clean-code",
"description": "Clean code principles adapted for TypeScript-first, functional development.",
"summary": "Clean code principles adapted for TypeScript-first, functional development.",
"icon": "🧹",
"version": "1.0.1",
"author": "DoubleslashSE",
"license": "MIT",
"category": "coding",
"tags": [
"clean-code",
"typescript",
"best-practices",
"refactoring",
"maintainability"
],
"supported_tools": [
"claude",
"codex",
"claude-code"
],
"risk_factors": [
"external_commands",
"network",
"filesystem"
]
},
"security_audit": {
"risk_level": "safe",
"is_blocked": false,
"safe_to_publish": true,
"summary": "All 93 static findings are FALSE POSITIVES. This is a documentation-only skill containing educational content about clean code principles. The static analyzer detected patterns in TypeScript code examples within markdown documentation (template literals, fetch calls, constant declarations) and misinterpreted them as security issues. No executable code, network operations, file system access, or system commands exist in this skill. The content consists solely of educational code examples demonstrating software engineering best practices.",
"risk_factor_evidence": [
{
"factor": "external_commands",
"evidence": [
{
"file": "reference.md",
"line_start": 6,
"line_end": 27
},
{
"file": "reference.md",
"line_start": 27,
"line_end": 30
},
{
"file": "reference.md",
"line_start": 30,
"line_end": 40
},
{
"file": "reference.md",
"line_start": 40,
"line_end": 43
},
{
"file": "reference.md",
"line_start": 43,
"line_end": 62
},
{
"file": "reference.md",
"line_start": 62,
"line_end": 67
},
{
"file": "reference.md",
"line_start": 67,
"line_end": 92
},
{
"file": "reference.md",
"line_start": 92,
"line_end": 95
},
{
"file": "reference.md",
"line_start": 95,
"line_end": 122
},
{
"file": "reference.md",
"line_start": 122,
"line_end": 125
},
{
"file": "reference.md",
"line_start": 125,
"line_end": 143
},
{
"file": "reference.md",
"line_start": 143,
"line_end": 148
},
{
"file": "reference.md",
"line_start": 148,
"line_end": 175
},
{
"file": "reference.md",
"line_start": 175,
"line_end": 181
},
{
"file": "reference.md",
"line_start": 181,
"line_end": 184
},
{
"file": "reference.md",
"line_start": 184,
"line_end": 214
},
{
"file": "reference.md",
"line_start": 214,
"line_end": 217
},
{
"file": "reference.md",
"line_start": 217,
"line_end": 221
},
{
"file": "reference.md",
"line_start": 221,
"line_end": 242
},
{
"file": "reference.md",
"line_start": 242,
"line_end": 246
},
{
"file": "reference.md",
"line_start": 246,
"line_end": 269
},
{
"file": "reference.md",
"line_start": 269,
"line_end": 273
},
{
"file": "reference.md",
"line_start": 273,
"line_end": 301
},
{
"file": "reference.md",
"line_start": 301,
"line_end": 305
},
{
"file": "reference.md",
"line_start": 305,
"line_end": 346
},
{
"file": "reference.md",
"line_start": 346,
"line_end": 350
},
{
"file": "reference.md",
"line_start": 350,
"line_end": 371
},
{
"file": "SKILL.md",
"line_start": 18,
"line_end": 27
},
{
"file": "SKILL.md",
"line_start": 27,
"line_end": 31
},
{
"file": "SKILL.md",
"line_start": 31,
"line_end": 44
},
{
"file": "SKILL.md",
"line_start": 44,
"line_end": 48
},
{
"file": "SKILL.md",
"line_start": 48,
"line_end": 65
},
{
"file": "SKILL.md",
"line_start": 65,
"line_end": 71
},
{
"file": "SKILL.md",
"line_start": 71,
"line_end": 80
},
{
"file": "SKILL.md",
"line_start": 80,
"line_end": 95
},
{
"file": "SKILL.md",
"line_start": 95,
"line_end": 99
},
{
"file": "SKILL.md",
"line_start": 99,
"line_end": 111
},
{
"file": "SKILL.md",
"line_start": 111,
"line_end": 112
},
{
"file": "SKILL.md",
"line_start": 112,
"line_end": 116
},
{
"file": "SKILL.md",
"line_start": 116,
"line_end": 145
},
{
"file": "SKILL.md",
"line_start": 145,
"line_end": 154
},
{
"file": "SKILL.md",
"line_start": 154,
"line_end": 176
},
{
"file": "SKILL.md",
"line_start": 176,
"line_end": 180
},
{
"file": "SKILL.md",
"line_start": 180,
"line_end": 205
},
{
"file": "SKILL.md",
"line_start": 205,
"line_end": 211
},
{
"file": "SKILL.md",
"line_start": 211,
"line_end": 221
},
{
"file": "SKILL.md",
"line_start": 221,
"line_end": 225
},
{
"file": "SKILL.md",
"line_start": 225,
"line_end": 240
},
{
"file": "SKILL.md",
"line_start": 240,
"line_end": 244
},
{
"file": "SKILL.md",
"line_start": 244,
"line_end": 271
},
{
"file": "SKILL.md",
"line_start": 271,
"line_end": 275
},
{
"file": "SKILL.md",
"line_start": 275,
"line_end": 289
},
{
"file": "SKILL.md",
"line_start": 289,
"line_end": 293
},
{
"file": "SKILL.md",
"line_start": 293,
"line_end": 303
},
{
"file": "SKILL.md",
"line_start": 303,
"line_end": 309
},
{
"file": "SKILL.md",
"line_start": 309,
"line_end": 318
},
{
"file": "SKILL.md",
"line_start": 318,
"line_end": 322
},
{
"file": "SKILL.md",
"line_start": 322,
"line_end": 345
}
]
},
{
"factor": "network",
"evidence": [
{
"file": "reference.md",
"line_start": 221,
"line_end": 221
},
{
"file": "reference.md",
"line_start": 308,
"line_end": 308
},
{
"file": "reference.md",
"line_start": 319,
"line_end": 319
},
{
"file": "reference.md",
"line_start": 25,
"line_end": 25
},
{
"file": "skill-report.json",
"line_start": 6,
"line_end": 6
},
{
"file": "SKILL.md",
"line_start": 51,
"line_end": 51
},
{
"file": "SKILL.md",
"line_start": 57,
"line_end": 57
},
{
"file": "SKILL.md",
"line_start": 64,
"line_end": 64
},
{
"file": "SKILL.md",
"line_start": 190,
"line_end": 190
},
{
"file": "SKILL.md",
"line_start": 198,
"line_end": 198
}
]
},
{
"factor": "filesystem",
"evidence": [
{
"file": "SKILL.md",
"line_start": 20,
"line_end": 20
},
{
"file": "SKILL.md",
"line_start": 21,
"line_end": 21
}
]
}
],
"critical_findings": [],
"high_findings": [],
"medium_findings": [],
"low_findings": [],
"dangerous_patterns": [],
"files_scanned": 3,
"total_lines": 901,
"audit_model": "claude",
"audited_at": "2026-01-17T05:34:28.895Z"
},
"content": {
"user_title": "Apply Clean Code Principles to TypeScript",
"value_statement": "Writing maintainable TypeScript code is challenging without clear guidance. This skill provides practical examples of DRY, KISS, and YAGNI principles to help you write cleaner, more readable code that your team can understand.",
"seo_keywords": [
"clean code",
"typescript",
"DRY principle",
"KISS principle",
"YAGNI",
"refactoring",
"maintainable code",
"Claude",
"Codex",
"Claude Code"
],
"actual_capabilities": [
"Explains DRY principle with TypeScript code examples",
"Demonstrates KISS principle through refactoring examples",
"Shows YAGNI principle with practical scenarios",
"Provides clean code checklist for TypeScript developers",
"Includes naming conventions and best practices",
"Contains async/await patterns and error handling examples"
],
"limitations": [
"Focuses on TypeScript and functional programming examples",
"Does not execute code or perform actual refactoring",
"Educational content only, no interactive features",
"Principles are guidance, not automated enforcement"
],
"use_cases": [
{
"target_user": "Junior TypeScript developers",
"title": "Learn Clean Code Fundamentals",
"description": "Understand DRY, KISS, and YAGNI principles through practical examples to improve code quality."
},
{
"target_user": "Senior developers conducting code reviews",
"title": "Guide Team Code Reviews",
"description": "Use as reference material during code reviews to explain clean code principles to team members."
},
{
"target_user": "Development teams establishing standards",
"title": "Establish Coding Standards",
"description": "Reference for creating team coding standards and best practices documentation."
}
],
"prompt_templates": [
{
"title": "Review Code for DRY Violations",
"scenario": "Analyzing repetitive code patterns",
"prompt": "Review this TypeScript code and identify DRY principle violations. Suggest refactoring to eliminate duplication: [paste code]"
},
{
"title": "Simplify Complex Code",
"scenario": "Refactoring over-engineered solutions",
"prompt": "This code seems over-engineered. Apply KISS principle to suggest a simpler implementation: [paste code]"
},
{
"title": "Check for YAGNI Violations",
"scenario": "Reviewing unnecessary abstractions",
"prompt": "Analyze this code for YAGNI violations. Identify features or abstractions that are not currently needed: [paste code]"
},
{
"title": "Complete Clean Code Review",
"scenario": "Comprehensive code quality assessment",
"prompt": "Perform a complete clean code review of this TypeScript code, checking against DRY, KISS, YAGNI, naming conventions, and the clean code checklist."
}
],
"output_examples": [
{
"input": "Review this function for clean code principles: const calc = (a,b,f) => f ? a*b*0.1 : a*b",
"output": [
"DRY: No duplication detected",
"KISS: Name 'calc' is unclear - should describe what it calculates",
"Naming: Parameter 'f' is not descriptive - use 'applyDiscount'",
"Suggestion: Rename to 'CalculateTotal' with 'applyDiscount' parameter"
]
},
{
"input": "Help me apply clean code to this validation logic that repeats in multiple places",
"output": [
"DRY: Extract validation into reusable function",
"KISS: Break complex validation into smaller focused checks",
"YAGNI: Only add validation rules you currently need",
"Naming: Use descriptive names like 'isValidEmail' instead of 'validate'"
]
}
],
"best_practices": [
"Use specific, descriptive names for all variables, methods, and classes",
"Keep methods small and focused on a single responsibility",
"Apply the Rule of Three before extracting common code"
],
"anti_patterns": [
"Do not abstract code until you have at least three similar implementations",
"Avoid premature optimization without measuring performance first",
"Do not create interfaces for single implementations without future plans"
],
"faq": [
{
"question": "Is this skill compatible with JavaScript projects?",
"answer": "Yes, principles apply to JavaScript too. Syntax may need slight adjustment but concepts are universal."
},
{
"question": "Can this skill analyze my actual code files?",
"answer": "No, this is educational content only. You will manually apply principles to your code."
},
{
"question": "How do I integrate this with my development workflow?",
"answer": "Use as reference during code reviews, pair programming, or when establishing team coding standards."
},
{
"question": "Is my code sent to external services?",
"answer": "No, this skill processes everything locally. No code is transmitted or stored externally."
},
{
"question": "What if my team uses different conventions?",
"answer": "Principles are universal. Adapt examples to match your team specific conventions and standards."
},
{
"question": "How does this compare to automated code analysis tools?",
"answer": "This provides educational context and reasoning. Use alongside tools like ESLint for comprehensive quality."
}
]
},
"file_structure": [
{
"name": "reference.md",
"type": "file",
"path": "reference.md",
"lines": 372
},
{
"name": "SKILL.md",
"type": "file",
"path": "SKILL.md",
"lines": 346
}
]
}