Back to blog
Quality
Claude Code

Stop Building What Already Exists: The Lazy Dev Mindset

Thang Doan
Thang Doan

I've seen juniors spend 3 days building a cache layer. The senior rewrote it in one line. Not because the senior is smarter, but because they know what not to build.

The rule

The laziest solution that actually works is the right solution.

That's not the same as cutting corners. It means: before writing code, ask whether you actually need to. Code is a liability. Every line you write is a line someone has to read, debug, and maintain. The less code you write, the less there is to break.

Example 1: Stop writing what shiki already does

This blog needed syntax highlighting for code blocks. Here's what a junior might build:

// ❌ Junior approach: 300+ lines, custom tokenizer
import { tokenize } from './my-tokenizer';
import { applyTheme } from './my-theme';

function CustomCodeHighlighter({ code, language }) {
  const tokens = tokenize(code, language);
  const themed = applyTheme(tokens, 'github-light');
  return (
    <pre className="code-block">
      {themed.map((line, i) => (
        <div key={i} className="code-line">
          {line.map((token, j) => (
            <span key={j} style={{ color: token.color }}>{token.text}</span>
          ))}
        </div>
      ))}
    </pre>
  );
}

Here's what we actually did, 14 lines, using shiki which was already in the project:

// ✅ Lazy approach: 14 lines, uses an installed dep
import { codeToHtml } from 'shiki';

async function CodeBlock({ value }: { value: { code: string; language?: string } }) {
  const html = await codeToHtml(value.code || '', {
    lang: value.language || 'text',
    theme: 'github-light',
  }).catch(() => codeToHtml(value.code || '', { lang: 'text', theme: 'github-light' }));

  return (
    <div
      className="my-4 rounded-lg overflow-x-auto text-sm [&>pre]:p-4"
      dangerouslySetInnerHTML={{ __html: html }}
    />
  );
}

Before writing anything, check what you already have installed. shiki does tokenization, theming, and language detection. One function call. The lesson: check your installed dependencies before writing a single line.

Example 2: The stdlib does it

Juniors love creating utility classes. A DateFormatter is the classic example:

// ❌ Junior approach: 40+ lines
class DateFormatter {
  private locale: string;
  private options: Intl.DateTimeFormatOptions;

  constructor(locale = 'en-US', options = {}) {
    this.locale = locale;
    this.options = options;
  }

  format(date: Date): string {
    return new Intl.DateTimeFormat(this.locale, this.options).format(date);
  }

  formatShort(date: Date): string {
    return new Intl.DateTimeFormat(this.locale, { dateStyle: 'short' }).format(date);
  }
  // ... more methods
}
// ✅ Lazy approach: one line, already in JavaScript
new Intl.DateTimeFormat('en-US', { dateStyle: 'medium' }).format(date)

JavaScript's Intl API handles locale, formatting, timezones, everything your class was going to rebuild. Before writing a helper, google "{thing} MDN" or "{thing} Node.js docs". The stdlib usually already handles it.

Example 3: You Aren't Gonna Need It (YAGNI)

A junior joins a 2-person startup and builds this:

// ❌ Junior approach: built for a scale that doesn't exist
class UserRoleManager {
  private roles: Map<string, Permission[]> = new Map();

  addRole(name: string, permissions: Permission[]) { /* ... */ }
  removeRole(name: string) { /* ... */ }
  assignRole(userId: string, role: string) { /* ... */ }
  checkPermission(userId: string, action: string): boolean { /* ... */ }
  // ... 80 more lines
}
// ✅ Lazy approach: for a 2-person startup
const isAdmin = user.role === 'admin';

Build for what's real today. If you get 10,000 users and 5 roles, you'll know exactly what the role system needs to handle. Right now you're guessing, and guessing is expensive.

The decision ladder

Before writing any code, go through this in order:

  1. Does this need to exist at all? (YAGNI)
  2. Does stdlib or the native platform already do it?
  3. Is there already an installed dependency that covers it?
  4. Can it be one line?
  5. Only then: write the minimum code that works.

Stop at the first rung that holds. If step 1 kills the idea, great, you just saved yourself days. If step 3 finds the solution, use it and move on.

Lazy is not careless

Lazy is 14 lines that work instead of 150 that might. It's checking what already exists before reaching for your keyboard. It's asking "does this need to exist?" before asking "how do I build this?"

The best code is the code you never had to write.

Recommended for you

Enjoyed this article?

Subscribe for new articles. No spam. Unsubscribe anytime.

By subscribing you agree to receive the newsletter. See the Privacy page.