What is KISS?
"Most systems work best if they are kept simple rather than made complicated."
KISS = Keep It Simple, Stupid
✓ Simplicity over complexity
✓ Readable over clever
✓ Obvious over obscure
✓ Maintainable over impressive
Simple Conditionals
// ❌ Bad - unnecessarily complex
function isAdult(age: number): boolean {
return age >= 18 ? true : false;
}
function hasAccess(user: User): boolean {
if (user.role === 'admin') {
return true;
} else {
return false;
}
}
// ✅ Good - simple and direct
function isAdult(age: number): boolean {
return age >= 18;
}
function hasAccess(user: User): boolean {
return user.role === 'admin';
}
Avoid Nested Logic
// ❌ Bad - deeply nested conditions
function processOrder(order: Order) {
if (order) {
if (order.items.length > 0) {
if (order.status === 'pending') {
if (order.payment) {
if (order.payment.verified) {
// Finally do something
return submitOrder(order);
}
}
}
}
}
return null;
}
// ✅ Good - early returns, flat structure
function processOrder(order: Order) {
if (!order) return null;
if (order.items.length === 0) return null;
if (order.status !== 'pending') return null;
if (!order.payment?.verified) return null;
return submitOrder(order);
}
Clear Variable Names
// ❌ Bad - cryptic names
const d = new Date();
const t = d.getTime();
const x = users.filter(u => u.a > 18 && u.s === 'active');
// ✅ Good - descriptive names
const currentDate = new Date();
const timestamp = currentDate.getTime();
const activeAdultUsers = users.filter(
user => user.age > 18 && user.status === 'active'
);
Simple Functions
// ❌ Bad - one function doing too much
function handleUserRegistration(data: any) {
// Validate
if (!data.email || !data.email.includes('@')) throw new Error('Invalid email');
if (!data.password || data.password.length < 8) throw new Error('Weak password');
// Hash password
const salt = generateSalt();
const hashedPassword = hash(data.password + salt);
// Create user
const user = { ...data, password: hashedPassword, salt };
// Save to database
database.users.insert(user);
// Send welcome email
emailService.send(data.email, 'Welcome!', welcomeTemplate);
// Log analytics
analytics.track('user_registered', { email: data.email });
return user;
}
// ✅ Good - small, focused functions
function validateRegistration(data: RegistrationData) {
if (!data.email?.includes('@')) throw new Error('Invalid email');
if (!data.password || data.password.length < 8) throw new Error('Weak password');
}
function createUser(data: RegistrationData): User {
const hashedPassword = hashPassword(data.password);
return { ...data, password: hashedPassword };
}
function handleUserRegistration(data: RegistrationData) {
validateRegistration(data);
const user = createUser(data);
saveUser(user);
sendWelcomeEmail(user.email);
trackRegistration(user.email);
return user;
}
Straightforward Data Structures
// ❌ Bad - over-engineered structure
interface UserData {
metadata: {
identity: {
primary: {
name: {
first: string;
last: string;
};
};
};
contact: {
electronic: {
email: {
primary: string;
};
};
};
};
}
// ✅ Good - flat and simple
interface User {
firstName: string;
lastName: string;
email: string;
}
Avoid Clever Code
// ❌ Bad - clever but confusing
const r = a => a.reduce((p, c) => (p[c] = (p[c] || 0) + 1, p), {});
// What does this do? Who knows without studying it.
// ✅ Good - clear and readable
function countOccurrences(items: string[]): Record<string, number> {
const counts: Record<string, number> = {};
for (const item of items) {
counts[item] = (counts[item] || 0) + 1;
}
return counts;
}
Simple Error Messages
// ❌ Bad - vague or overly technical
throw new Error('E_INVLD_USR_CRED_AUTH_FAIL_0x003');
throw new Error('Something went wrong');
// ✅ Good - clear and actionable
throw new Error('Invalid email or password. Please try again.');
throw new Error('User not found. Check the user ID and try again.');
Minimal Dependencies
// ❌ Bad - library for simple tasks
import { leftPad } from 'left-pad';
import { isNumber } from 'is-number';
import { isArray } from 'is-array';
// ✅ Good - use built-in features
const padded = String(num).padStart(5, '0');
const isNum = typeof value === 'number';
const isArr = Array.isArray(value);
Simple API Design
// ❌ Bad - complex API with many options
createButton({
type: 'primary',
size: 'medium',
variant: 'filled',
elevation: 2,
ripple: true,
disableRipple: false,
fullWidth: false,
loading: false,
loadingPosition: 'center',
// ... 20 more options
});
// ✅ Good - sensible defaults, minimal config
createButton({ label: 'Submit' });
createButton({ label: 'Cancel', variant: 'secondary' });
Signs Your Code is Too Complex
⚠️ Warning signs:
• You need comments to explain what code does
• New team members struggle to understand it
• You can't remember how it works after a week
• Small changes require touching many files
• Unit tests are hard to write
• Debugging takes hours instead of minutes
Quick Reference
| Complex | Simple |
|---|---|
| Nested ifs | Early returns |
| Clever one-liners | Readable loops |
| Deep hierarchies | Flat structures |
| Many parameters | Config objects |
| Cryptic names | Descriptive names |
| Large functions | Small functions |
Related Principles
KISS works well with:
• YAGNI - You Aren't Gonna Need It
• DRY - Don't Repeat Yourself
• SOLID - Object-oriented design
• Unix Philosophy - Do one thing well
"Simplicity is the ultimate sophistication" - Leonardo da Vinci
"Everything should be made as simple as possible, but not simpler" - Einstein