Systeric / Docs
Open App →

Keep It Simple

The best code is the least code that solves the real problem. Not the cleverest, not the most flexible, not the most future-proof. The smallest thing that works, reads plainly, and can be changed later without fear. Simplicity is not a lack of skill; holding a system simple as it grows is one of the hardest things in engineering, and the clearest mark of an engineer who understands what they’re doing.

Complexity feels like progress while you’re writing it. A configurable engine, a clever abstraction, a layer that handles cases nobody’s asked for, they all feel like good engineering in the moment. Then they become the thing every future change has to route around. Complexity is not paid once. It’s paid on every read, every edit, every onboarding, forever.


Build for the Problem You Have#

What’s expected: You build what the task actually requires, not what you imagine it might require later.

The most expensive habit in engineering is solving problems you don’t have yet. You’re asked for one flat discount code, and you build a rules engine with percentage tiers, stacking logic, and time windows, because “we’ll probably need it.” Usually you never do, and the speculative machinery sits there as a tax on everyone, harder to read, harder to change, full of paths no test covers because no feature uses them.

Over-built for an imagined future
applyDiscounts(cart, {
  rules: DiscountRule[],   // tiers, stacking,
  strategy: "best" | "sum",// schedules, currencies…
  schedule?: DateWindow,
  stackable?: boolean,
}) // 200 lines. One coupon in production.
Built for the problem you have
applyCode(cart, code) {
  const pct = VALID_CODES[code] ?? 0
  return round(subtotal(cart) * (1 - pct))
} // Add tiers the day a tier exists.

How to get there: Ask “what does this task actually require, today?” and build exactly that. When you feel the pull to generalize, name the concrete second use case that justifies it. If you can’t name one that exists, you’re guessing, and a guess in code is a cost you pay now for a benefit that may never arrive. The simple version is not the lazy version; it’s the one you can extend the day a real second case shows up, which is the right day to add it. This is the Define instinct, “is there a simpler version of this?”, carried into the code.

The pull to over-build shows up everywhere, not just in pricing: a generic plugin system for one integration, a caching layer for a query that runs twice a day, a configurable workflow engine for a two-step process. Same test every time, name the second real case that exists today, or don’t build for it.


Choose Boring#

What’s expected: You reach for the familiar, proven tool before the new, exciting one, and you can justify any novelty you introduce.

Novelty is a cost. A new library, a new pattern, a new abstraction, each is one more thing every teammate has to learn, every reviewer has to evaluate, and every future engineer has to maintain. Sometimes it’s worth it. Usually the boring option, the one already in the codebase, the standard-library function, the pattern the team already knows, solves the problem with none of the tax.

How to get there: Before introducing something new, check what’s already here. Most problems have already been solved somewhere in the codebase or by a well-worn library; matching the existing pattern is almost always better than inventing a cleaner-looking one. Reserve novelty for where it earns its keep, a genuinely new problem the old tools can’t handle, and when you do reach for it, say why in the definition so the whole team signs off on the cost, not just you.


Readable Beats Clever#

What’s expected: Someone who’s never seen this code can read it and understand what it does, without you narrating.

Code is read far more often than it’s written, and the reader is usually tired, in a hurry, and debugging something else. Clever code, the dense one-liner, the trick that saves three lines, the abstraction that’s elegant only once you hold the whole thing in your head, taxes every one of those reads. Plain, obvious code that a newcomer follows on the first pass is worth more than clever code that impresses on the third.

Bad: a nested ternary that computes shipping, tax, and discount in one expression to save space.

Good: three named steps, subtotal, afterDiscount, withTax, that read top to bottom like the sentence they represent.

The test is simple: could a new teammate read this and tell you what it does, without you standing over their shoulder? If it needs narration, it isn’t finished, in exactly the way a design that needs a tooltip isn’t finished. And in an AI-assisted codebase this matters more, not less: you are the one who has to understand, direct, and vouch for what the machine wrote. Code you can’t read plainly is code you can’t actually own.


Simplicity Is a Constraint Decision#

Keeping things simple is the same discipline as Constraints & Cost on the product side: every line you add is a line the team carries forever. The most senior move in engineering is often deletion, removing a layer, collapsing two things into one, saying “we don’t need this.” A smaller system that does the job is not a lesser achievement than a larger one. It’s the harder, better one.


Next: Cover the Edge Cases