PageSourceSearch

https://enterprise-jamstack.netlify.app/complexity-is-a-code-smell

html enterprise-jamstack.netlify.app collected 2026-10-03 10:42:12 UTC 22,350 bytes, 3 lines download raw bytes

1<!DOCTYPE html><html lang="en"><head>
1<script async="" src="https://platform.twitter.com/widgets.js" charSet="utf-8"></script>
1<meta name="viewport" content="width=device-width"/><meta charSet="utf-8"/><meta name="twitter:card" content="summary_large_image"/><meta name="twitter:site" content="jlengstorf"/><meta name="twitter:creator" content="jlengstorf"/><meta property="og:type" content="website"/><meta property="og:image:width" content="1280"/><meta property="og:image:height" content="628"/><meta property="og:site_name" content="Enterprise Jamstack"/><meta property="author" content="jason lengstorf"/><meta property="keywords" content=""/><title>Complexity Is a Code Smell:
21 Strategy for More Productive Teams</title><meta name="robots" content="index,follow"/><meta name="googlebot" content="index,follow"/><meta name="description" content="Complexity is unavoidable, but how we introduce it to our codebase matters. Learn how to avoid architectural choices that tank team efficiency."/><meta property="og:title" content="Complexity Is a Code Smell:
31 Strategy for More Productive Teams"/><meta property="og:description" content="Complexity is unavoidable, but how we introduce it to our codebase matters. Learn how to avoid architectural choices that tank team efficiency."/><meta property="og:image" content="https://enterprisejamstack.com/images/complexity-is-a-code-smell/[email protected]"/><meta name="next-head-count" content="18"/><link rel="preload" href="/_next/static/css/35f20e858c564fb02033.css" as="style"/><link rel="stylesheet" href="/_next/static/css/35f20e858c564fb02033.css" data-n-g=""/><noscript data-n-css=""></noscript><link rel="preload" href="/_next/static/chunks/webpack-245f049e565ebf942e09.js" as="script"/><link rel="preload" href="/_next/static/chunks/framework.9b1461276aaf369266fd.js" as="script"/><link rel="preload" href="/_next/static/chunks/commons.b5ce34496128bbae93e0.js" as="script"/><link rel="preload" href="/_next/static/chunks/main-bd3343d45f1f161ebc4c.js" as="script"/><link rel="preload" href="/_next/static/chunks/29107295.5be7ccfb405ce3cd12f4.js" as="script"/><link rel="preload" href="/_next/static/chunks/6de3ae7f6649ef404b8d04129d2818da72dbecd9.6d9a6bd3d52ccf5750b2.js" as="script"/><link rel="preload" href="/_next/static/chunks/1234f736d1e84ee97edcb9b7d1af6eebf0aaf46a.14b12c390f5ee35d9723.js" as="script"/><link rel="preload" href="/_next/static/chunks/pages/_app-129bf0790441b0bc6dae.js" as="script"/><link rel="preload" href="/_next/static/chunks/7550e981870f63b34341087d51d881ebfd6e862f.5c9ba2c374f65a4f0351.js" as="script"/><link rel="preload" href="/_next/static/chunks/1195a8f2a97491bc18195b699495da91743c3836.1ed310e23fde974a8a3d.js" as="script"/><link rel="preload" href="/_next/static/chunks/35901236d5436c4b511c4a4ef6b7fa8cbdcdd2d8.484560d1759993e0ac26.js" as="script"/><link rel="preload" href="/_next/static/chunks/pages/complexity-is-a-code-smell-94342e9bd9c7f59d3911.js" as="script"/><style data-emotion-css=""></style></head><body><div id="__next"><div style="position:fixed;z-index:9999"></div><div class="flex flex-col min-h-screen"><nav class="absolute top-0 left-0 w-full p-5"><div class="flex items-center justify-between w-full max-w-screen-lg mx-auto"><a class="inline-flex flex-col text-base font-medium leading-none origin-left transform scale-90 group sm:scale-100" href="/"><h1 class="text-base leading-tight sm:text-lg">Enterprise Jamstack</h1><div class="text-sm sr-only opacity-80 sm:not-sr-only">with Jason Lengstorf</div></a><div class="flex items-center space-x-2 text-sm font-medium sm:text-base"><a class="px-2 py-1 transition-all duration-300 ease-in-out transform rounded-full sm:px-3 sm:py-2 hover:bg-indigo-50 hover:scale-105 hover:text-indigo-500" href="/blog">Blog</a><button type="button" class="inline-flex items-center px-4 py-2 font-medium text-gray-900 transition-all duration-200 ease-in-out transform bg-gray-100 rounded-full hover:scale-105 hover:text-indigo-500 hover:bg-indigo-50"><svg aria-hidden="true" focusable="false" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24"><g stroke-linecap="square" stroke-linejoin="miter" stroke-width="2" fill="none" stroke="currentColor" stroke-miterlimit="10"><path d="M1,13v6a2,2,0,0,0,2,2H21a2,2,0,0,0,2-2V13"></path><path d="M23,8V5a2,2,0,0,0-2-2H3A2,2,0,0,0,1,5V8l11,6Z" stroke="currentColor"></path></g></svg><div class="pl-2">Subscribe</div></button></div></div></nav><main class="px-5 flex-grow md:flex flex-col justify-center items-center ">
3<article class="w-full py-8 mx-auto space-y-8 sm:py-24"><h1 class="max-w-screen-lg px-0 mx-auto text-4xl font-bold text-center sm:pt-16 pt-14 lg:text-5xl sm:text-4xl lg:px-5">Complexity Is a Code Smell:<br/>1 Strategy for More Productive Teams</h1><header class="max-w-screen-lg mx-auto"><img width="1024" height="576" alt="" class="rounded-md" srcSet="/images/complexity-is-a-code-smell/cover.png 1x, /images/complexity-is-a-code-smell/[email protected] 2x"/></header><div class="prose lg:prose-xl sm:prose-lg max-w-none"></div><main class="max-w-screen-md pb-8 mx-auto"><div class="prose lg:prose-xl sm:prose-lg max-w-none"><p>Complexity is unavoidable in modern frontends. However, some complexity is inevitable (e.g. the frontend has to do a lot of stuff), and some is unnecessary.</p><p>Before adding complexity, we need to carefully weight the trade-offs and make sure it&#x27;s necessary. <strong><a href="/tech-stack-changes-culture">Our software choices have a large impact on our team culture</a>, and too much complexity can grind your productivity to a halt.</strong></p><blockquote class="twitter-tweet" data-dnt="true" data-theme="dark"><p lang="en" dir="ltr">if you need a whiteboard to explain your frontend architecture, it’s too complicated</p>— Jason Lengstorf (@jlengstorf) <a href="https://twitter.com/jlengstorf/status/1382711865340354564?ref\_src=twsrc%5Etfw">April 15, 2021</a></blockquote> 
3<script async="" src="https://platform.twitter.com/widgets.js" charSet="utf-8"></script>
3<p><strong>When frontends become too complex, it becomes harder and slower for any given developer to take a new feature from idea to production.</strong> Every change ends up crossing between multiple teams, with all the inefficiencies and slowdowns that cross-team coordination brings with it.</p><h2 id="complex-systems-make-individual-developers-slower">Complex systems make individual developers slower.</h2><p>At the individual level, developers need to understand how the changes they make affect the whole system. In complex systems, that&#x27;s a huge amount of context required to maintain the code. <strong>Too much complexity can cause accidental breakage or, worse, a resistance to starting tasks because the codebase is overwhelming.</strong></p><blockquote><p>Hot take: letting codebase complexity spiral out of control is how we ended up with a whole industry that feels like it can <em>only</em> hire senior frontend developers.</p></blockquote><h2 id="complex-systems-make-teams-slower">Complex systems make teams slower.</h2><p>At the team level, complexity creates silos. How many people truly understand the whole system? Are there people on your team who <em>can&#x27;t</em> take a vacation because they&#x27;re the only one that knows how a critical system works?</p><p><strong>If people don&#x27;t feel confident making changes without a sign-off from the person with all the complexity locked away in their brain, the team can only move as fast as that bottleneck allows.</strong></p><h2 id="complex-systems-make-entire-companies-slower">Complex systems make entire companies slower.</h2><p><strong>At an company level, complexity creates bureaucracy.</strong> Cross-functional systems require multiple teams to coordinate, execute, review, and deliver together.</p><p>How often does the team feel stuck because they&#x27;re not sure who makes the final decision on how to move forward?</p><p>Complex systems frequently require joint ownership, which creates a huge risk of ambiguity and all the slowdowns and tension that come along with it.</p><h2 id="complex-systems-lead-to-frustration-and-low-morale">Complex systems lead to frustration and low morale.</h2><p>Teams that feel like they can&#x27;t ship things get frustrated, feel guilty (even though the slowness is out of their control), and eventually burn out and quit.</p><p><strong>Complex software architecture <em>directly</em> contributes to turnover and low engagement.</strong></p><h2 id="contain-complexity-through-decoupling">Contain complexity through decoupling.</h2><p>Simplicity doesn&#x27;t mean removing systems; it means adding clarity between discrete parts of the system. It&#x27;s challenging to hold a large amount of complexity in our heads, but we can easily manage a long series of individual, simple tasks.</p><p>Simplicity means <a href="/clever-solutions">resisting the urge to over-engineer a system</a> and instead building solutions that unlock long-term, whole-team productivity.</p><p><strong>This is at the root of the Jamstack architecture: we can accomplish incredible complex tasks using simple software architecture through decoupling systems and containing complexity in manageable chunks.</strong></p><h2 id="clear-boundaries-between-systems-create-clarity">Clear boundaries between systems create clarity.</h2><p><strong>If two parts of a system only communicate via a well-defined API, we no longer need to think about anything outside the boundary when we work on the code.</strong> This means each engineer needs less context to make meaningful changes — they <em>only</em> need to know what the API contract looks like and make sure that doesn&#x27;t break.</p><h2 id="optimize-for-deletion">Optimize for deletion.</h2><p><strong>A great way to create clear boundaries is to think of each system as a discrete unit that can be fully replaced without any adjacent systems requiring updates.</strong> <a href="https://jason.af/optimize-for-deletion">Optimizing for deletion</a> makes it possible to create independent, simple systems that interact with each other to accomplish complex tasks.</p><p>We use systems like this all the time: when we call a REST API, we have no idea if the underlying service is written in Java, Go, Node, or some language we&#x27;ve never heard of. We don&#x27;t know if it&#x27;s serverless or running on Kubernetes or hosted on a single machine in the CEO&#x27;s closet.</p><p>What we <em>do</em> know is that if we hit the <code>/post/123</code> endpoint, we&#x27;ll get back a JSON object with post data:</p>
3<pre class="sm:mx-0 -mx-5 sm:rounded-sm overflow-x-scroll rounded-none prism-code language-json" style="color:#d6deeb;background-color:#0C0C0C"><div class="token-line" style="font-size:90%"><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span></div><div class="token-line" style="font-size:90%"><span class="token plain">  </span><span class="token property" style="color:rgb(128, 203, 196)">&quot;id&quot;</span><span class="token operator" style="color:rgb(127, 219, 202)">:</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">123</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span></div><div class="token-line" style="font-size:90%"><span class="token plain">  </span><span class="token property" style="color:rgb(128, 203, 196)">&quot;title&quot;</span><span class="token operator" style="color:rgb(127, 219, 202)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">&quot;Complexity Is a Code Smell&quot;</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span></div><div class="token-line" style="font-size:90%"><span class="token plain">  </span><span class="token property" style="color:rgb(128, 203, 196)">&quot;body&quot;</span><span class="token operator" style="color:rgb(127, 219, 202)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">&quot;Complexity is unavoidable in modern frontends. However, some...&quot;</span><span class="token plain"></span></div><div class="token-line" style="font-size:90%"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span></div></pre><p>We know how to send a request to the API and how to expect results to come back — that&#x27;s all we <em>need</em> to know to use the system!</p><p>Under the hood, the backend team could replace the entire codebase and — as long as the API contract stays the same — our frontend would never need to know or care. It can happily keep sending that query for as long as the API contract remains intact.</p><h2 id="decoupled-systems-make-individual-developers-faster">Decoupled systems make individual developers faster.</h2><p>By making the boundaries clear, individual developers need significantly less context to make changes to a given system. This prevents knowledge silos and removes the barrier to entry for early and mid-career devs (at least on the &quot;only a senior can understand our codebase&quot; front). This also means that it&#x27;s less daunting to start and more likely that an individual can handle a whole project on their own if necessary.</p><h2 id="decoupled-systems-make-teams-faster">Decoupled systems make teams faster.</h2><p><strong>A decoupled system allows the team to share knowledge more easily and provide more redundancy and coverage.</strong> This means everyone can actually take a vacation without leaving the team stuck.</p><p>And, even if someone <em>is</em> the sole owner of a system, by putting clear boundaries around it the team can work on other parts of the product and not need to worry about accidental side effects that require pulling that person off vacation to fix.</p><h2 id="decoupled-systems-make-companies-faster">Decoupled systems make companies faster.</h2><p><strong>Decoupled systems can be built and deployed independently.</strong> Teams will still collaborate and work cross-team, but their projects won&#x27;t be tightly coupled.</p><p>Firm boundaries between systems allow for easier mocking and clearer discussion around requirements. This removes ambiguity and decreasing the number of things that require joint ownership.</p><h2 id="complexity-is-unavoidable--but-we-can-keep-it-under-control">Complexity is unavoidable — but we can keep it under control.</h2><p>There&#x27;s no getting around the fact that modern frontend development requires complexity. However, if we&#x27;re intentional about how complexity is introduced, we can still provide clarity and simplicity in the softw
3are we write.</p><p><strong>Being intentional with our tech choices makes all the difference between a team that feels bogged down and demoralized by complexity — or empowered and engaged by decoupled architecture.</strong></p></div><div id="subscribe" class="relative py-16 lg:py-40 xl:py-48 md:py-32 sm:py-24"><h3 class="max-w-screen-sm pb-4 mx-auto text-3xl text-center md:text-4xl">Unlock the Full Potential of<!-- --> <strong>Scalable &amp; Production Ready</strong> Jamstack Architecture for Your Team</h3><h4 class="text-base text-center md:text-lg">Be the first to hear about updates to Enterprise Jamstack course</h4><form class="grid w-full max-w-md grid-cols-1 gap-8 px-5 py-8 mx-auto bg-gray-1000" action="https://app.convertkit.com/forms/1886128/subscriptions" method="post"><div class="flex flex-col"><label for="fields[first_name]">First name</label><input type="text" class="px-4 py-3 text-lg bg-gray-100 border-none rounded-md form-input" id="fields[first_name]" name="fields[first_name]" placeholder="David"/></div><div class="flex flex-col"><label for="email_address">Email <span class="text-gray-400">*</span></label><input type="email" class="px-4 py-3 text-lg bg-gray-100 border-none rounded-md form-input" id="email_address" name="email_address" placeholder="[email protected]" required=""/></div><button type="submit" class="flex items-center justify-center px-4 py-4 text-lg font-semibold text-center text-white transition-all duration-300 ease-in-out transform rounded-md group bg-gradient-to-r hover:shadow-xl from-indigo-600 to-indigo-500 hover:scale-105"><span class="">Get Good at Jamstack</span></button></form><div class="mt-4 text-sm text-center opacity-60">No spam, unsubscribe any time.</div></div></main><footer class="flex items-center px-5 pb-16 -mx-5 bg-gray-100 lg:pb-0"><div class="grid max-w-screen-lg grid-cols-1 mx-auto lg:grid-cols-2"><div class="flex flex-col py-16 md:py-5"><div class="flex flex-row items-start sm:items-end md:flex-row"><div class="flex flex-shrink-0 transform md:translate-y-16 bg-white sm:bg-transparent sm:max-w-[216px] max-w-[130px]"><img srcSet="/images/jason-lengstorf-teaching.jpg 1x, /images/[email protected] 2x" width="683" height="909" alt="Jason Lengstorf, the author of EnterpriseJamstack.com, photographed while teaching a workshop" class="transition-all duration-300 ease-in-out rounded-md filter saturate-0 hover:saturate-100"/></div><div class="flex flex-col pb-8 pl-5 md:pl-10 "><span class="text-sm">Written by</span><span class="text-xl font-semibold">Jason Lengstorf</span><p class="pt-1">a principal developer experience engineer at Netlify and the host of Learn With Jason, a live-streamed video show where he pairs with people in the community to learn something new in 90 minutes.</p></div></div></div><div class="flex flex-col items-center justify-center pt-16 lg:pt-0"><h5 class="pb-2 text-lg font-medium">Share this article with your co-workers</h5><div class="inline-flex flex-wrap items-center justify-center"><a class="flex items-center px-2 py-1 mr-2 text-sm leading-6 text-white transition-colors duration-100 ease-in-out rounded-md bg-lightBlue-500 hover:bg-lightBlue-600" href="https://twitter.com/intent/tweet/?text=Complexity%20Is%20a%20Code%20Smell%3A%20%20%0A1%20Strategy%20for%20More%20Productive%20Teams%0A%0Aarticle%20by%20%40jlengstorf%20&amp;url=https%3A%2F%2Fenterprisejamstack.com%2Fcomplexity-is-a-code-smell"><svg focusable="false" aria-hidden="true" class="mr-1" xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24"><g fill="currentColor"><path fill="none" d="M0 0h24v24H0z"></path><path d="M22.162 5.656a8.384 8.384 0 0 1-2.402.658A4.196 4.196 0 0 0 21.6 4c-.82.488-1.719.83-2.656 1.015a4.182 4.182 0 0 0-7.126 3.814 11.874 11.874 0 0 1-8.62-4.37 4.168 4.168 0 0 0-.566 2.103c0 1.45.738 2.731 1.86 3.481a4.168 4.168 0 0 1-1.894-.523v.052a4.185 4.185 0 0 0 3.355 4.101 4.21 4.21 0 0 1-1.89.072A4.185 4.185 0 0 0 7.97 16.65a8.394 8.394 0 0 1-6.191 1.732 11.83 11.83 0 0 0 6.41 1.88c7.693 0 11.9-6.373 11.9-11.9 0-.18-.005-.362-.013-.54a8.496 8.496 0 0 0 2.087-2.165z"></path></g></svg><span>Tweet</span></a><button type="button" class="flex items-center px-2 py-1 text-sm leading-6 transition-colors duration-100 ease-in-out bg-white rounded-md hover:bg-gray-200"><svg focusable="false" aria-hidden="true" class="mr-1" xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24"><g fill="none"><path d="M13.828 10.172a4 4 0 0 0-5.656 0l-4 4a4 4 0 1 0 5.656 5.656l1.102-1.101m-.758-4.899a4 4 0 0 0 5.656 0l4-4a4 4 0 0 0-5.656-5.656l-1.1 1.1" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path></g></svg><span>Copy link to clipboard</span></button></div></div></div></footer></article><div class="-left-full sm:-left-1/2 rotate-0 fixed bottom-24 -translate-x-3 rounded-md shadow-xl bg-indigo-500 transform transition-all ease-in-out duration-300  text-white text-lg"><div class="max-w-md p-5 pl-10"><div class="w-48 text-lg font-medium leading-tight">Interested in learning more about Jamstack?</div><div class="pt-4 space-x-2"><button type="button" class="px-3 py-1 font-medium text-black bg-white rounded-md">Sure</button><button type="button" class="px-3 py-1 text-white bg-transparent roun
3ded-md">No</button><button class="absolute p-2 text-lg top-1 right-1"><svg focusable="false" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="10" height="10" viewBox="0 0 12 12"><g fill="currentColor"><path d="M10.707,1.293a1,1,0,0,0-1.414,0L6,4.586,2.707,1.293A1,1,0,0,0,1.293,2.707L4.586,6,1.293,9.293a1,1,0,1,0,1.414,1.414L6,7.414l3.293,3.293a1,1,0,0,0,1.414-1.414L7.414,6l3.293-3.293A1,1,0,0,0,10.707,1.293Z" fill="currentColor"></path></g></svg></button></div></div></div></main></div></div>
3<script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/complexity-is-a-code-smell","query":{},"buildId":"OW7C2994nFLOsFsFU90Ot","runtimeConfig":{},"nextExport":true,"autoExport":true,"isFallback":false}</script>
3<script nomodule="" src="/_next/static/chunks/polyfills-38409c49aeb95e9aebf0.js"></script>
3<script src="/_next/static/chunks/webpack-245f049e565ebf942e09.js" async=""></script>
3<script src="/_next/static/chunks/framework.9b1461276aaf369266fd.js" async=""></script>
3<script src="/_next/static/chunks/commons.b5ce34496128bbae93e0.js" async=""></script>
3<script src="/_next/static/chunks/main-bd3343d45f1f161ebc4c.js" async=""></script>
3<script src="/_next/static/chunks/29107295.5be7ccfb405ce3cd12f4.js" async=""></script>
3<script src="/_next/static/chunks/6de3ae7f6649ef404b8d04129d2818da72dbecd9.6d9a6bd3d52ccf5750b2.js" async=""></script>
3<script src="/_next/static/chunks/1234f736d1e84ee97edcb9b7d1af6eebf0aaf46a.14b12c390f5ee35d9723.js" async=""></script>
3<script src="/_next/static/chunks/pages/_app-129bf0790441b0bc6dae.js" async=""></script>
3<script src="/_next/static/chunks/7550e981870f63b34341087d51d881ebfd6e862f.5c9ba2c374f65a4f0351.js" async=""></script>
3<script src="/_next/static/chunks/1195a8f2a97491bc18195b699495da91743c3836.1ed310e23fde974a8a3d.js" async=""></script>
3<script src="/_next/static/chunks/35901236d5436c4b511c4a4ef6b7fa8cbdcdd2d8.484560d1759993e0ac26.js" async=""></script>
3<script src="/_next/static/chunks/pages/complexity-is-a-code-smell-94342e9bd9c7f59d3911.js" async=""></script>
3<script src="/_next/static/OW7C2994nFLOsFsFU90Ot/_buildManifest.js" async=""></script>
3<script src="/_next/static/OW7C2994nFLOsFsFU90Ot/_ssgManifest.js" async=""></script>
3</body></html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.