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>Developers: weâd all suffer a lot less if we werenât so dang clever</title><meta name="robots" content="index,follow"/><meta name="googlebot" content="index,follow"/><meta name="description" content="Cracking hard problems with clever solutions is super satisfying for developers. But if weâre careless, we can cause more problems than we solve."/><meta property="og:title" content="Developers: weâd all suffer a lot less if we werenât so dang clever"/><meta property="og:description" content="Cracking hard problems with clever solutions is super satisfying for developers. But if weâre careless, we can cause more problems than we solve."/><meta property="og:image" content="https://enterprisejamstack.com/images/clever-solutions/[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/clever-solutions-041e269133ccd8158a4b.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 ">
1<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">Developers: weâd all suffer a lot less if we werenât so dang clever</h1><header class="max-w-screen-lg mx-auto"><img width="1024" height="576" alt="" class="rounded-md" srcSet="/images/clever-solutions/cover.png 1x, /images/clever-solutions/[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>A clever solution is the decision to introduce novel patterns, uncommon workarounds, and/or additional layers of abstraction to solve an underlying problem.</p><p>Many of the tools we use daily were once clever solutions, so I want to stress that <strong>a clever solution is not automatically a bad solution.</strong> The problem isn't that developers are clever.</p><p>The problem is that developers <em>want</em> to be clever, so they tend to reach for clever solutions first, introducing unnecessary complexity and overhead when a simpler solution is available. Developers love hard problems. It's exciting to stare down a challenge, break it down, and â using nothing but our super smart brains and Stack Overflow â create a new and exciting solution to the problem.</p><p><strong>Clever solutions are a huge risk for creating knowledge silos, technical debt, process bottlenecks, and organizational sluggishness.</strong></p><h2 id="clever-solutions-come-in-many-forms">Clever solutions come in many forms</h2><p>In my career, I've seen some <em>doozies</em> when it comes to clever solutions that started out exciting and ended up costing us more time and stress than they saved.</p><ul><li><strong>a custom content management system</strong> because "WordPress is too bloated". It did less and sucked more and I eventually convinced all of my clients to use WordPress instead.</li><li><strong>a bespoke query language</strong> because the existing solutions donât support some esoteric edge case.</li><li><strong>hand-rolled functions from well-maintained open source libraries</strong> for... reasons?</li><li><strong>an "all-in-one" abstraction</strong> over all the business logic of a 30-team application.</li><li><strong>a "massively scalable" generic approach to data manipulation</strong> used exactly once in the codebase. What we needed to do was get values out of an object. What we ended up with was a schema definition file and generic <code>getValueFromStructuredObject</code> functions.</li></ul><p>I've seen teams craft fully customized build systems (that no one but the creator can get to work), devilishly clever caching strategies (that everyone works around because they don't understand them), data normalization layers, proxies to do a bit of business logic so they aren't blocked on the backend devs, and so, so many more clever solutions.</p><p>These projects start with best intentions.</p><p>They end as Byzantine legacy code that frustrates and slows down everyone on the team.</p><p><img src="https://res.cloudinary.com/jlengstorf/image/upload/q_auto,f_auto,w_1200/v1618795702/enterprise-jamstack/clever-solutions.jpg" alt="Kat Maddox illustrates in a tweet what Iâm about trying to explain in 1,300 words"/></p><p><em><a href="https://twitter.com/ctrlshifti/status/1288745146759000064">Kat Maddox</a> illustrates in a tweet what Iâm trying to explain in 1,300 words.</em></p><h2 id="clever-solutions-come-with-strings-attached">Clever solutions come with strings attached.</h2><p>When you invent solutions, you gain the freedom and flexibility to do anything you feel is necessary to solve a given problem â but you also take on a <em>ton of work</em> to keep it healthy after it is deployed to customers.</p><ul><li><p><strong>Clever solutions require ongoing maintenance, support, and development.</strong> Now you need to maintain, support, and evolve that codebase to keep it functioning.</p></li><li><p><strong>Clever solutions create a training and documentation burden.</strong> Customized, clever solutions make it harder to onboard new developers, and often results in knowledge silos. This feels bad for the team and worse for the developer who's about to get paged in the middle of dinner because they're the only one who can unblock the company.</p></li><li><p><strong>Clever solutions create liabilities.</strong> If the creator leaves, the clever solution is now legacy code no one understands.</p></li></ul><p>Each of these obligations fight for the âactual priorityâ spot on the priority list.</p><p>Before long, the context is lost and the company just took on more tech debt. Dealing with tech debt often leads to a new clever solution, and the cycle c
1ontinues.</p><h2 id="we-need-to-think-of-downstream-effects-when-designing-solutions">We need to think of downstream effects when designing solutions.</h2><p>Programming is an interesting career because it can be both a career <em>and</em> a hobby.</p><p>I fall into this camp. I love puzzles, so teasing apart a complicated problem hits me right in the dopamine.</p><p>But it almost always feels like a chore to learn an existing system or tool.</p><p>It's vital for long-term personal, team, and company success to learn how to recognize when optimizing for fun will end up destructive.</p><p><strong>We need to stop implementing clever solutions as a way to avoid learning how other people's code works.</strong> Instead, we need to look for great solutions that set us up for success now <em>and</em> in the future.</p><h3 id="great-solutions-reduce-complexity-and-overhead">Great solutions reduce complexity and overhead.</h3><p><strong>In my career, many of my biggest wins involved removing huge chunks of complexity in favor of a straightforward system that could be maintained by developers at any experience level.</strong></p><p>Removing complexity increases the team's ability to reason about the codebase. This makes it more maintainable, which makes it less of a bottleneck.</p><p><strong>This is one of the reasons I'm so bullish on the Jamstack architecture.</strong></p><p>By moving to a precompiled, decoupled architecture, I get to remove the complexity of running and deploying servers. And by choosing a platform-as-a-service provider to handle the building and deployment of the frontend, I also get to offload all the overhead of managing that process â it becomes automatic. (I'm a little biased because I work there, but I use <a href="https://ntl.fyi/3ttY2ug">Netlify</a> for this.)</p><h3 id="the-best-solution-is-the-one-everyone-can-understand">The best solution is the one everyone can understand.</h3><p><strong>Solving a problem in a way that the whole team can understand, maintain, and extend is far more valuable than a solution that is computationally clever but opaque.</strong></p><p>Our assessment of how effective someone's solution is can't stop with the initial delivery; it needs to include ongoing maintenance effort estimates and onboarding costs. Looking for established tools and platforms â and the documentation, maintenance, and community support that comes with them â is a great default action. <strong>Building something custom should rarely be the first choice.</strong></p><h2 id="cleverness-as-a-last-resort">Cleverness as a last resort.</h2><p>There will absolutely be cases where the problems we're facing are truly unique and the solution can't be simple.</p><p>That's okay!</p><p>Our challenge is to thoroughly weigh the trade-offs and make sure that we're only choosing the clever solution when something simpler isn't an option, rather than immediately chasing clever solutions because it's more fun for us.</p><p><strong>Building the skill to be discerning about when and how we deploy our cleverness can be the difference between a maintainable codebase and a crushing pile of tech debt.</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 & 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><div class="prose lg:prose-xl sm:prose-lg max-w-none"><h4 id="acknowledgments">Acknowledgments</h4><p><em>Thanks to <a href="https://kellanem.com/">Kellan Elliott-McCrea</a>, whose <a href="https://twitter.com/kellan/status/1336004177567354882">public thoughts on team challenges at Dropbox</a> got me started on this post, and to <a href="https://cjcodes.com/">Chris Johnson</a> who originally shared Kellan's thread with me. Thanks to the <a href="https://www.partycorgi.com/">Party Corgi Discord</a> and <a href="https://joelhooks.com/">Joel Hooks</a> for helpful edits and feedback.</em></p></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=Developers%3A%20we%E2%80%99d%20all%20suffer%20a%20lot%20less%20if%20we%20weren%E2%80%99t%20so%20dang%20clever%0A%0Aarticle%20by%20%40jlengstorf%20&url=https%3A%2F%2Fenterprisejamstack.com%2Fclever-solutions"><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
1ded-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>
1<script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/clever-solutions","query":{},"buildId":"OW7C2994nFLOsFsFU90Ot","runtimeConfig":{},"nextExport":true,"autoExport":true,"isFallback":false}</script>
1<script nomodule="" src="/_next/static/chunks/polyfills-38409c49aeb95e9aebf0.js"></script>
1<script src="/_next/static/chunks/webpack-245f049e565ebf942e09.js" async=""></script>
1<script src="/_next/static/chunks/framework.9b1461276aaf369266fd.js" async=""></script>
1<script src="/_next/static/chunks/commons.b5ce34496128bbae93e0.js" async=""></script>
1<script src="/_next/static/chunks/main-bd3343d45f1f161ebc4c.js" async=""></script>
1<script src="/_next/static/chunks/29107295.5be7ccfb405ce3cd12f4.js" async=""></script>
1<script src="/_next/static/chunks/6de3ae7f6649ef404b8d04129d2818da72dbecd9.6d9a6bd3d52ccf5750b2.js" async=""></script>
1<script src="/_next/static/chunks/1234f736d1e84ee97edcb9b7d1af6eebf0aaf46a.14b12c390f5ee35d9723.js" async=""></script>
1<script src="/_next/static/chunks/pages/_app-129bf0790441b0bc6dae.js" async=""></script>
1<script src="/_next/static/chunks/7550e981870f63b34341087d51d881ebfd6e862f.5c9ba2c374f65a4f0351.js" async=""></script>
1<script src="/_next/static/chunks/1195a8f2a97491bc18195b699495da91743c3836.1ed310e23fde974a8a3d.js" async=""></script>
1<script src="/_next/static/chunks/35901236d5436c4b511c4a4ef6b7fa8cbdcdd2d8.484560d1759993e0ac26.js" async=""></script>
1<script src="/_next/static/chunks/pages/clever-solutions-041e269133ccd8158a4b.js" async=""></script>
1<script src="/_next/static/OW7C2994nFLOsFsFU90Ot/_buildManifest.js" async=""></script>
1<script src="/_next/static/OW7C2994nFLOsFsFU90Ot/_ssgManifest.js" async=""></script>
1</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.