Software Engineering Laws for Product Development
Exploring two famous software engineering laws — Zawinski's Law and Atwood's Law — with real-world examples, why they happen, and what product teams can do about them.
Zawinski's Law: Every program attempts to expand until it can read mail
This law is a cynical but accurate observation on the lifecycle of successful software. It states that the natural trajectory of any useful program is to accumulate features until it becomes a bloated, unfocused platform.
The reference to "reading mail" is metaphorical; it represents the ultimate, all-encompassing feature that is completely disconnected from the program's original purpose. The law warns that feature creep is not an accident but an inevitable gravitational force that must be actively resisted.
Why It Happens
- Success Attracts Requests → More users = more diverse needs, leading to endless feature requests.
- The Feature Parity Arms Race → Competitive pressure forces teams to mimic rivals’ feature sets.
- Organizational Gravity → Teams often measure progress by outputting more features rather than simplifying or refining existing ones.
Real-World Examples
-
Slack → From Chat to Work Hub Slack began as a team chat tool. Over time, it expanded into file sharing, voice/video calls, workflows, and app integrations. While powerful, many users feel it lost the simplicity that made it beloved.
-
Photoshop → The Everything-Tool Originally a photo editor, Photoshop ballooned into 3D, video editing, UI design, and more. This complexity created space for focused competitors like Figma and Canva.
What To Do About It
- Have a Written Product Vision → Define what the product is and is not. Use it to justify saying "no."
- Make "No" the Default → Features should prove their worth before being added.
- Focus on the Core Job To Be Done → Ask: Does this feature help users solve their main problem better? If not, skip it.
- Favor Integration Over Assimilation → Build APIs instead of absorbing every adjacent feature request.
Atwood's Law: Any application that can be written in JavaScript, will eventually be written in JavaScript
This law isn’t about technical superiority — it’s about ecosystem gravity. JavaScript, with its ubiquity across browsers, servers, and npm, has become the gravitational center of application development. If something can be written in JavaScript, history shows that it eventually will.
Why It Happens
- Unavoidable Ubiquity → Every browser runs JavaScript, giving it an unbeatable foothold.
- The Full-Stack Advantage → Node.js unified frontend and backend under one language.
- Ecosystem Gravity → npm is the largest package library, creating a self-reinforcing adoption loop.
- Low Barrier to Entry → Easy learning curve + massive talent pool ensures sustained dominance.
Real-World Examples
-
Google Docs & Office 365 Once desktop-only applications, word processors and spreadsheets now run in browsers, built largely on JavaScript.
-
Figma A design workflow traditionally tied to heavy desktop software was rebuilt in the browser using JavaScript + WebAssembly. Result: real-time collaboration and rapid adoption.
-
VS Code Instead of C++, Microsoft built VS Code on Electron (Node.js + Chromium). Despite skepticism, it’s now the world’s most popular code editor.
What To Do About It
- Acknowledge JavaScript as the Default → For many apps, JS/TS is the baseline. Only deviate with strong reasoning.
- Define Escape Hatches → For high-performance, low-level, or data science tasks, deliberately choose languages like Go, Rust, or Python.
- Mandate TypeScript → For any non-trivial project, types are not optional. They’re essential for scaling maintainability.
- Invest in Polyglot Capabilities → Don’t fall into monoculture. Develop expertise in complementary languages where JS falls short.
Final Thoughts
- Zawinski’s Law reminds us that feature creep is a constant gravitational pull.
- Atwood’s Law highlights JavaScript’s inevitability in modern development.
Engineering leaders must acknowledge these forces — then design deliberate strategies to manage them.
- Protect focus with a clear product vision.
- Avoid bloat with strategic refusal and integrations.
- Embrace JavaScript’s ubiquity but know when to escape its orbit.
Great products succeed not by ignoring these laws, but by navigating them wisely.