<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Folafunmi</title>
    <description>The latest articles on Forem by Folafunmi (@folafunmidb).</description>
    <link>https://forem.com/folafunmidb</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F214977%2F92a2579f-36c5-49c2-b9a6-ba0010004b86.jpeg</url>
      <title>Forem: Folafunmi</title>
      <link>https://forem.com/folafunmidb</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/folafunmidb"/>
    <language>en</language>
    <item>
      <title>Modern Frontend: Growing Responsibilities</title>
      <dc:creator>Folafunmi</dc:creator>
      <pubDate>Fri, 29 Apr 2022 18:12:49 +0000</pubDate>
      <link>https://forem.com/playfulprogramming/modern-frontend-growing-responsibilities-3ghl</link>
      <guid>https://forem.com/playfulprogramming/modern-frontend-growing-responsibilities-3ghl</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TLDR:&lt;/strong&gt; The increasing complexity in the frontend ecosystem should trigger a reassessment of valuation, job descriptions, and general overview of frontend developers.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;Lewis Caroll description of  Wonderland, as a place where “It takes all the running you can do, to keep in the same place. If you want to get somewhere else, you must run at least twice as fast as that!”, which epitomizes the current landscape of frontend engineering where standards evolve and change is the only constant.&lt;/p&gt;

&lt;p&gt;Several months ago, I stumbled upon an intelligently written &lt;a href="https://bradfrost.com/blog/post/front-of-the-front-end-and-back-of-the-front-end-web-development/" rel="noopener noreferrer"&gt;piece&lt;/a&gt; by &lt;a href="https://bradfrost.com/" rel="noopener noreferrer"&gt;Brad Frost&lt;/a&gt; on what had then begun to be called &lt;a href="https://css-tricks.com/the-great-divide/" rel="noopener noreferrer"&gt;The Great Divide&lt;/a&gt;. This made the rounds. In this article, he outlined two functionally distinct aspects of web development: &lt;strong&gt;Front-of-the-front-end web development&lt;/strong&gt; and &lt;strong&gt;Back-of-the-front-end web development&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;NB: In this post, I do not give heed to the nuances of syntax. As such "Front-End", "Frontend", "Front end" would refer to the same aspects of web development neither do I concern myself with the semantic differences, if there are any, between "Developer" and "Engineer". All terms would be used interchangeably in this write-up.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It’s become more prominent in recent times that the term "Front-End Developer/Engineer" needs an overhaul, with reasons stemming from the ever-expanding surface area of responsibilities that have to be catered for and categorized as "Front-End".&lt;/p&gt;

&lt;p&gt;In line with this, various points were raised stating that the minefield that is CSS is a big enough challenge. As bluntly put by &lt;a href=""&gt;Mandy Michael&lt;/a&gt; in her article, &lt;a href="https://medium.com/@mandy.michael/is-there-any-value-in-people-who-cannot-write-javascript-d0a66b16de06" rel="noopener noreferrer"&gt;Is there any value in people who cannot write JavaScript?”&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When every new website on the internet has perfect, semantic, accessible HTML and exceptionally executed, accessible CSS that works on every device and browser, then you can tell me that these languages are not valuable on their own. Until then we need to stop devaluing CSS and HTML.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here she puts forth the brilliant idea, that although a divide exists, it doesn't exist for the casting down of one side or the other.&lt;/p&gt;

&lt;p&gt;Addressing the differences between developers &lt;a href=""&gt;Ronald Long&lt;/a&gt;, in the context of peace, wrote in his &lt;a href="https://webdesigntips.blog/web-design/css-tricks/the-great-divide/" rel="noopener noreferrer"&gt;article&lt;/a&gt; on the subject:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Yes, there is a divide, but no, neither side is any more valuable than the other.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It is worthy of note that the divide being spoken of here refers to how the broader ecosystem splits the responsibilities of the frontend developer into two sections. Those who major in HTML and CSS (front-of-the-frontend developers) sometimes referred to as UI developers and those that are far more dependent on Javascript (back-of-the-frontend developers).&lt;/p&gt;

&lt;p&gt;However, most times this distinction only serves to educate the developers themselves as employers and recruiters do not give heed to the growing landscape of responsibilities of the frontend developer. As such most frontend developers are expected to be both front-of-the-frontend and back-of-the-frontend savvy.&lt;/p&gt;

&lt;p&gt;This results in a , as requirements for frontend developers now differ significantly from those of a few years ago. The developer community, in an attempt to capture the current state of frontend engineering, has adopted the term &lt;strong&gt;Modern Frontend&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Sadly, this doesn't appear to have gained traction with many people. The common sentiment (in my experience) by other engineers and those in management, towards what is regarded as frontend, hasn't shifted to reflect the expansion. Particularly in the context of regard and valuation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Possible Reasons
&lt;/h2&gt;

&lt;p&gt;Based on personal experience as well as those of the numerous articles I've read on the topic, I can classify the justification for the resilience to change in perception into two classes:&lt;br&gt;
Sentiment&lt;br&gt;
Responsibility&lt;br&gt;
These are highlighted in the reasons that follow.&lt;/p&gt;

&lt;p&gt;Recently, I came across a brilliant article on &lt;a href="https://www.zhenghao.io/posts/system-design-interviews" rel="noopener noreferrer"&gt;Frontend Vs. Backend System Design Interviews&lt;/a&gt;, where the author gave his two cents (more than that though) on the context, similarities, and differences in interview processes between jobs listed for Frontend and Backend Developers/Engineers.&lt;/p&gt;

&lt;p&gt;The author, &lt;a href="https://twitter.com/he_zhenghao" rel="noopener noreferrer"&gt;Zhenghao&lt;/a&gt;, also expressed a concern for a &lt;a href="https://www.zhenghao.io/posts/system-design-interviews#career-ceiling" rel="noopener noreferrer"&gt;Career Ceiling&lt;/a&gt; which seems to be exclusive to frontend engineers only. This is in line with intermittent opinions that pop up every now and then saying or implying that &lt;em&gt;"frontend engineering isn't real engineering"&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The author along with anyone that has paid attention to the frontend ecosystem knows that frontend is just as much as challenging as backend.&lt;/p&gt;

&lt;p&gt;However, it's quite important to recognize the underpinnings of such statements. Paraphrasing some of the opinions from &lt;a href="https://twitter.com/he_zhenghao" rel="noopener noreferrer"&gt;Zhenghao&lt;/a&gt; in &lt;a href="https://www.zhenghao.io/posts/system-design-interviews" rel="noopener noreferrer"&gt;this post&lt;/a&gt;, possible reasons include:&lt;/p&gt;

&lt;h3&gt;
  
  
  Inertia
&lt;/h3&gt;

&lt;p&gt;The reluctance to a change in the mentality that frontend is not real engineering can be seen quite clearly in differences in compensation.&lt;/p&gt;

&lt;p&gt;At the time of writing, estimations from &lt;a href="https://glassdoor.com/" rel="noopener noreferrer"&gt;Glassdoor&lt;/a&gt; inform of a pay gap of 10 - 70% between Frontend and Backend developers for roles with similar experience depending on the industry and location.&lt;/p&gt;

&lt;p&gt;Also, this can be seen in the roles of those that move up the career ladder. Depicted in how most (from those I’ve seen) of VP of Engineering or CTOs were previously Backend Engineers or Infrastructure(DevOps) Engineers. I give more details on my reasoning around this in the section on experience.&lt;/p&gt;

&lt;h3&gt;
  
  
  Economics
&lt;/h3&gt;

&lt;p&gt;This reasoning values an engineer by the amount of money(resources) you control. This can also be referred to as responsibility.&lt;/p&gt;

&lt;p&gt;As noted by &lt;a href="https://twitter.com/he_zhenghao" rel="noopener noreferrer"&gt;Zhenghao&lt;/a&gt; in his article,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I had this realization that when I was going through the backend system design interviews vs. the frontend system design interviews - the technical topics those interviews tend to cover let me think about some economic reasoning leading to the perception of a "Frontend Ceiling” as well. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Backend systems require more expensive resources to run, be it Digital Ocean droplets, EC2 instances etc. These compute seem to require much more to both maintain and scale.&lt;/p&gt;

&lt;p&gt;Frontend systems on the other hand run on the user's devices, which costs a company essentially...NOTHING! No maintenance is needed. No bills.&lt;/p&gt;

&lt;p&gt;Essentially, bad backend code or DevOps integrations can lead to a hefty bill from AWS that'd make anyone cry, but bad frontend code can be seen to mostly affect a user to a certain degree and doesn't drain the funds of the company.&lt;/p&gt;

&lt;h3&gt;
  
  
  Length of processes
&lt;/h3&gt;

&lt;p&gt;Frontend applications live on the user's device, spun up, and terminated with the open and close of a browser tab. While backend application servers however run for months and or years.&lt;/p&gt;

&lt;p&gt;Flawed frontend code only lives long enough to affect the currently open tab. Flawed backend code however can and often will accumulate, leading to slowdowns or crashes. One can be ignored the other most certainly cannot.&lt;/p&gt;

&lt;h3&gt;
  
  
  Experience
&lt;/h3&gt;

&lt;p&gt;This point is from my personal experiences in the tech space. It's easy to associate the term frontend with inexperience. In reality, it is relatively newer due to the technologies that surround it.&lt;/p&gt;

&lt;p&gt;From my research, when web browsers were first released there wasn’t much of a “front-end.” There were static HTML pages and CGI scripts that generated HTML.&lt;/p&gt;

&lt;p&gt;Asynchronous JavaScript and XML (Ajax), from its inception in 2004 (or 1999 depending on who you ask) then until its proliferation in 2008/2009 periods wasn't widely adopted.&lt;/p&gt;

&lt;p&gt;JavaScript, which serves as the base for modern frontend, wasn't as used till frameworks that emerged around the 2010s. Developers around these periods worked largely on the backend (server-based tasks, databases, etc). Backend developers that then worked on user interfaces are styled, Fullstack Developers.&lt;/p&gt;

&lt;p&gt;This largely leaves &lt;strong&gt;mostly&lt;/strong&gt; newer developers who focus on the front-facing interface to embrace the “frontend” description. Thereby easy to associate them with fewer years of experience.&lt;/p&gt;

&lt;p&gt;Coupled with the fact that frontend (referring to HTML, CSS, and JS) has the least barrier to entry–a web browser. As such beginner web developers are advised to start with HTML, CSS, and JS which are the fundamentals of frontend.&lt;/p&gt;

&lt;p&gt;These are brilliant points!👏🏾&lt;/p&gt;

&lt;p&gt;However, I hold other opinions which do not invalidate the points listed above, but rather take into account how broad the Front End ecosystem has become.&lt;/p&gt;

&lt;p&gt;This is due, largely, to user expectations which have led frontend down a road of solutions that succumb to incidental complexity.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Frontend isn't working hard to become as complex if not more than backend.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The need to adapt to the end-user, to maintain a stable pace with advancements in browser technology, devices, web standards, etc has led to newer(sometimes weirder) solutions in the frontend ecosystem.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The definition of the frontend role has expanded to include human-computer interaction, responsiveness, UI optimization and reusability, browsers, devices, and accessibility amongst others.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Over the last couple of years, there has been an explosion of options for nearly everything in the ecosystem some of which I highlight in the next section.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rising Frontend Complexity
&lt;/h2&gt;

&lt;p&gt;With almost every passing week emerges new abbreviations and concepts, further expanding the body of knowledge. &lt;/p&gt;

&lt;p&gt;Sophisticated abstractions intended to ease the workload on engineers tend to demand new understanding and inspire new ways of building apps. Complexity in itself doesn't attenuate, it only evolves.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Change is rapid and unpredictable.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The increase in internet usage shows that web developers now have to consider a larger audience, tougher demands, and offer better user experience by whatever means necessary.&lt;/p&gt;

&lt;p&gt;All in a space that's come under more scrutiny in recent times with Google's announcement to rank pages based on Core Web Vitals. Frontend developers as such have to resort to more nuanced technologies to meet egregious and ever-rising demands while balancing what tradeoffs may come their way.&lt;/p&gt;

&lt;p&gt;Modern frontend has spurred the demand for pixel-perfect, real-time, reactive, concurrently rendered, responsive sites with minimal bundle size, accessible HTML &amp;amp; CSS, stylish UI with snappy responses, optimistic updates, cached data, and performant animations across all devices to which newer features can be easily added without a hit to performance or developer productivity.😰&lt;/p&gt;

&lt;p&gt;Really, is that all? Want my left hand too?🙄&lt;/p&gt;

&lt;p&gt;There also exist different ways to achieve similar results, all with their nuances and learning curves. This has led to the further rise in complexity of frontend architecture. Some categories of these choices include:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Tooling
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Frameworks:&lt;/strong&gt; React, Vue, Angular, Solid, Svelte, Qwik&lt;br&gt;
&lt;strong&gt;Frameworks:&lt;/strong&gt; NextJS, Remix, NuxtJS, Sveltekit&lt;br&gt;
&lt;strong&gt;Bundlers:&lt;/strong&gt; Vite, Snowpack, Webpack, Parcel, Rome&lt;br&gt;
&lt;strong&gt;State managers:&lt;/strong&gt; Redux, Zustand, Recoil, Pinia, Vuex&lt;br&gt;
&lt;strong&gt;Package managers:&lt;/strong&gt; npm, Yarn (1,2,3), pnpm&lt;br&gt;
&lt;strong&gt;Serverless:&lt;/strong&gt; Netlify functions, Vercel edge functions, Cloudflare workers, AWS Lambda&lt;br&gt;
&lt;strong&gt;Project structure:&lt;/strong&gt; 😂 &lt;/p&gt;

&lt;p&gt;Frontend tools are no longer presented as optional features. Developers can only handle so much complexity on their own before relying on useful abstractions to solve routine tasks.&lt;/p&gt;

&lt;p&gt;Libraries and tools were born out of necessity, the need to adapt to tougher requirements as well as the desire for the better developer experience. The model of modern frontend therefore favours configuration and flexibility.&lt;/p&gt;

&lt;p&gt;The plethora of choices when it comes to tooling is both a blessing and a curse. For example, if some better architectural model surfaces tomorrow there’s a good chance it’d be available sooner rather than later. Here, it’s a blessing.&lt;/p&gt;

&lt;p&gt;However, this means frontend developers have to weigh &lt;code&gt;x+1&lt;/code&gt; factors in making the choice of tools to use. &lt;a href="https://vadimdemedes.com/" rel="noopener noreferrer"&gt;Vadim Demedes&lt;/a&gt; laments about this in &lt;a href="https://reviewbunny.app/blog/dont-make-me-think-or-why-i-switched-to-rails-from-javascript-spas" rel="noopener noreferrer"&gt;his article&lt;/a&gt; where he explains why he switch to rails from javascript single page applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Various rendering and hydrations modes
&lt;/h3&gt;

&lt;p&gt;It really does seem like everyone is trying to come up with three letter acronyms for new rendering modes.&lt;/p&gt;

&lt;p&gt;CSR - Client Side Rendering&lt;br&gt;
ISR - Incremental Static Regeneration &lt;br&gt;
DPR - Distributed Persisted Rendering&lt;br&gt;
DSG - Deferred Static Generation &lt;br&gt;
SSR - Server Side Rendering &lt;br&gt;
SSG - Static Site Generation&lt;br&gt;
There’s more coming!&lt;/p&gt;

&lt;p&gt;These would be explained in a different blog post. Watch out! &lt;/p&gt;

&lt;p&gt;Also, for the types of applications there’s the choice between:&lt;br&gt;
SPA - Single Page Applications&lt;br&gt;
MPA - Multiple Page Applications&lt;br&gt;
Hybrid&lt;br&gt;
The best resource I have come across on the topic can be found &lt;a href="https://kissdigital.com/blog/single-page-application-how-spa-works-and-how-it-differs-from-mpa" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Not to mention the different modes of hydration i.e Progressive hydration, selective hydration, or sidestepping hydration altogether and going for a framework that favours &lt;a href="https://www.builder.io/blog/from-static-to-interactive-why-resumability-is-the-best-alternative-to-hydration" rel="noopener noreferrer"&gt;resumability&lt;/a&gt; (thank you &lt;a href="https://twitter.com/mhevery" rel="noopener noreferrer"&gt;Misiko&lt;/a&gt;!).&lt;/p&gt;

&lt;p&gt;This might seem to be a challenge mostly faced by authors and maintainers of libraries, who work immensely to create sane abstractions for the developer community. &lt;/p&gt;

&lt;p&gt;For example, to switch from SSR to ISR in NextJS can be the addition of a single line of code.&lt;/p&gt;

&lt;p&gt;However, note that frontend developers being burdened about user experience and performance have to weigh the tradeoffs between the different modes and the community that surrounds them. &lt;/p&gt;

&lt;p&gt;At the point of writing, it is quite possible to ship relatively complex web apps built without an explicit backend. Thanks to hybrid frameworks frontend has gone fullstack!&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Evolution of the web and user expectations
&lt;/h3&gt;

&lt;p&gt;The web is poised to become its own operating system, allowing developers to bypass building the same app for different platforms.&lt;/p&gt;

&lt;p&gt;With the rising CPU performance of devices, phones and computers can do more and users have come to expect more. This can be seen in Line Engineering’s &lt;a href="https://engineering.linecorp.com/en/blog/the-baseline-for-web-development-in-2022/" rel="noopener noreferrer"&gt;report&lt;/a&gt; on web development.&lt;/p&gt;

&lt;p&gt;Versions of popular apps such as VScode, Photoshop etc are now available on the web.&lt;/p&gt;

&lt;p&gt;The usefulness of a site ultimately comes down to user interactions. This can yield beautiful rewards for the business as a whole when done right as well as reap alarming consequences when gotten wrong. &lt;/p&gt;

&lt;p&gt;In 2015, &lt;a href="https://www.invisionapp.com/" rel="noopener noreferrer"&gt;Invision&lt;/a&gt; published an &lt;a href="https://www.invisionapp.com/inside-design/statistics-on-user-experience/" rel="noopener noreferrer"&gt;article&lt;/a&gt; with compilation of statistics on the effect of UX on businesses. Simply put, the &lt;a href="https://www.toptal.com/designers/ux/roi-of-ux-convince-executives" rel="noopener noreferrer"&gt;ROI of UX&lt;/a&gt; cannot be overlooked.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I wrote this piece, not as a swipe at other forms of engineering, because they do have various choices to make and also have to handle rising complexity. The point of this article was to show that frontend ought to be appreciated alongside the immense work being done by engineers all around.&lt;/p&gt;

&lt;p&gt;Truly, this is a hard and exciting time to be a frontend developer. As Kevin Ball put it, in his &lt;a href="https://blog.logrocket.com/the-increasing-nature-of-frontend-complexity-b73c784c09ae/" rel="noopener noreferrer"&gt;article&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The technology is moving so fast it’s hard to keep up, the ecosystem is fragmented, and there is tremendous pressure for even individuals to meet and exceed the user experience standards set by massive billion-dollar companies.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Work requirements are evolving in all spheres, likewise, it's important to update our assessments of all roles.&lt;/p&gt;

&lt;p&gt;This is an incredible time for innovation, there have never been more opportunities, and there has never been more powerful tooling.&lt;/p&gt;

&lt;p&gt;This is an amazing time to be a Front End developer ✌🏾&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=grSxHfGoaeg" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=grSxHfGoaeg&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://webdesigntips.blog/web-design/css-tricks/the-great-divide/" rel="noopener noreferrer"&gt;https://webdesigntips.blog/web-design/css-tricks/the-great-divide/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.logrocket.com/the-increasing-nature-of-frontend-complexity-b73c784c09ae/" rel="noopener noreferrer"&gt;https://blog.logrocket.com/the-increasing-nature-of-frontend-complexity-b73c784c09ae/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.zhenghao.io/posts/system-design-interviews" rel="noopener noreferrer"&gt;https://www.zhenghao.io/posts/system-design-interviews&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://css-tricks.com/the-great-divide/" rel="noopener noreferrer"&gt;https://css-tricks.com/the-great-divide/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bradfrost.com/blog/post/front-of-the-front-end-and-back-of-the-front-end-web-development/" rel="noopener noreferrer"&gt;https://bradfrost.com/blog/post/front-of-the-front-end-and-back-of-the-front-end-web-development/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://engineering.linecorp.com/en/blog/the-baseline-for-web-development-in-2022/" rel="noopener noreferrer"&gt;https://engineering.linecorp.com/en/blog/the-baseline-for-web-development-in-2022/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://reviewbunny.app/blog/dont-make-me-think-or-why-i-switched-to-rails-from-javascript-spas" rel="noopener noreferrer"&gt;https://reviewbunny.app/blog/dont-make-me-think-or-why-i-switched-to-rails-from-javascript-spas&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>Tailwind vs Sass/SCSS: Structure and Consistency over Style and Comfort</title>
      <dc:creator>Folafunmi</dc:creator>
      <pubDate>Thu, 10 Mar 2022 13:13:18 +0000</pubDate>
      <link>https://forem.com/playfulprogramming/tailwind-vs-sassscss-structure-and-consistency-over-style-and-comfort-44cd</link>
      <guid>https://forem.com/playfulprogramming/tailwind-vs-sassscss-structure-and-consistency-over-style-and-comfort-44cd</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;For this article, I choose the totally non-controversial and completely innocent topic of CSS frameworks, particularly placing the growing Tailwind library and the dominant Sass/SCSS. &lt;/p&gt;

&lt;p&gt;Why? I just love violence 😈. But actually, having read several opinions on both sides of the aisle, I choose to air my views as a contribution to the ongoing debate regarding CSS frameworks. Who knows, someone might just find it useful 🤷🏾‍♂️&lt;/p&gt;

&lt;p&gt;It’s difficult to miss the appeal of Sass (Syntactically Awesome Style Sheets), which is an extension of CSS that provides features that seem to have been left out of CSS itself. It preserves the natural feel of writing CSS, but at what cost? 🤔&lt;/p&gt;

&lt;p&gt;Alternatively, Tailwind proposes a utility-first approach to CSS where styles pre-exist with classes that can be added to any HTML element. While this has developer experience (DX) benefits, it’s an unnatural way of writing CSS because you don’t actually write CSS, it’s already been written! Aren’t we just writing HTML then? Doesn’t this violate separations of concerns? 🤔&lt;/p&gt;

&lt;p&gt;It’s apparent that both Sass and Tailwind recognize that plain CSS needs help. Judging by the widespread adoption of both frameworks, the developer community seems to agree with this premise. As at the time of writing this, Sass had 7.1M+ weekly downloads while TailwindCSS had garnered 2.4M+ weekly downloads on NPM. In reality, these numbers represent the lower bound of their uses. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Both aim to increase the quality of life around writing CSS but their approach however differs.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What is Sass?
&lt;/h2&gt;

&lt;p&gt;Released in 2006, Sass (Syntactically Awesome Style Sheets) is a mature stylesheet language that’s compiled to CSS (Cascading Style Sheets). Essentially, Sass makes you write CSS more efficiently. It provides features with a fully CSS-compatible syntax.&lt;/p&gt;

&lt;p&gt;Sass is preprocessed into CSS. The Sass preprocessor (written in Dart or Ruby) takes input data in Sass or SCSS format and converts it to an output that's pure CSS. This is necessary because browsers can only read CSS code.&lt;/p&gt;

&lt;p&gt;This means when you run Sass/SCSS code, you're actually converting your code to CSS. That CSS code output is then used directly by a browser.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is SCSS?
&lt;/h3&gt;

&lt;p&gt;To clear up the confusion between Sass and SCSS, SCSS stands for “Sassy CSS” and is a more natural feel to CSS compared to the original Sass syntax. &lt;/p&gt;

&lt;p&gt;The initial Sass syntax uses indentation for nesting and provides a visual hierarchy in the code, its appearance is similar to Python or Ruby but unlike CSS. It uses the &lt;code&gt;.sass&lt;/code&gt; extension. &lt;/p&gt;

&lt;p&gt;SCSS on the other hand uses curly braces that better resemble regular CSS. It uses the &lt;code&gt;.scss&lt;/code&gt; extension.&lt;/p&gt;

&lt;p&gt;An example of indented Sass syntax from the official docs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="k"&gt;@mixin&lt;/span&gt; &lt;span class="nf"&gt;button-base&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;include&lt;/span&gt; &lt;span class="nf"&gt;typography&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;button&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;include&lt;/span&gt; &lt;span class="n"&gt;ripple-surface&lt;/span&gt;
  &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;include&lt;/span&gt; &lt;span class="n"&gt;ripple-radius-bounded&lt;/span&gt;

  &lt;span class="n"&gt;display&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;inline-flex&lt;/span&gt;
  &lt;span class="n"&gt;position&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;relative&lt;/span&gt;
  &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$button-height&lt;/span&gt;
  &lt;span class="n"&gt;border&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;
  &lt;span class="n"&gt;vertical-align&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;middle&lt;/span&gt;

  &lt;span class="o"&gt;&amp;amp;:&lt;/span&gt;&lt;span class="n"&gt;hover&lt;/span&gt;
    &lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;pointer&lt;/span&gt;

  &lt;span class="o"&gt;&amp;amp;:&lt;/span&gt;&lt;span class="n"&gt;disabled&lt;/span&gt;
    &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$mdc-button-disabled-ink-color&lt;/span&gt;
    &lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;default&lt;/span&gt;
    &lt;span class="n"&gt;pointer-events&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An example of SCSS syntax from the official docs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="k"&gt;@mixin&lt;/span&gt; &lt;span class="nf"&gt;button-base&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;@include&lt;/span&gt; &lt;span class="nd"&gt;typography&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;button&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;@include&lt;/span&gt; &lt;span class="nd"&gt;ripple-surface&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;@include&lt;/span&gt; &lt;span class="nd"&gt;ripple-radius-bounded&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;inline-flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;relative&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$button-height&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;vertical-align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;middle&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nd"&gt;:hover&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nd"&gt;:disabled&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$mdc-button-disabled-ink-color&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;default&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;pointer-events&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both perform the same function and have the same capabilities. However, SCSS syntax is more appealing, easier to learn, and personally, it’s the only one I’ve ever used.&lt;/p&gt;

&lt;h2&gt;
  
  
  Benefits of Sass
&lt;/h2&gt;

&lt;p&gt;Sass provides features that enable developers to move faster when working on a project. Some benefits include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Variables: Facilitates the DRY (Don’t Repeat Yourself) approach. Although regular CSS has this feature at the time of writing albeit with a different syntax.&lt;/li&gt;
&lt;li&gt;Mixins: Even DRY-er approach. This encapsulates certain rules into one.&lt;/li&gt;
&lt;li&gt;Functions: Useful for some folks, but not me 😅 🤷🏾‍♂️.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Read more &lt;a href="https://sass-lang.com/guide" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Sass/SCSS makes CSS feel more like a programming language, giving developers flexibility and ease. Typically, for none trivial cases Sass is more maintainable than native CSS as it's easier to collocate by nesting rules for hover and focus selectors.&lt;/p&gt;

&lt;p&gt;For example, this is the Sass/SCSS equivalent,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="nv"&gt;$button-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;$mdc-button-disabled-ink-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mh"&gt;#e4e4e4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nc"&gt;.button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;inline-flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;relative&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$button-height&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;vertical-align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;middle&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nd"&gt;:hover&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nd"&gt;:focus&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$mdc-button-disabled-ink-color&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nd"&gt;:disabled&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$mdc-button-disabled-ink-color&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;default&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;pointer-events&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Of this CSS,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;inline-flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;relative&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;vertical-align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;middle&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.button&lt;/span&gt;&lt;span class="nd"&gt;:hover&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.button&lt;/span&gt;&lt;span class="nd"&gt;:focus&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#e4e4e4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.button&lt;/span&gt;&lt;span class="nd"&gt;:disabled&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#e4e4e4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;default&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;pointer-events&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What is Tailwind?
&lt;/h2&gt;

&lt;p&gt;Contrary to Sass/SCSS, Tailwind adopts the atomic CSS style, using the term utility-classes to define a subset of the much broader term. &lt;/p&gt;

&lt;p&gt;Utility classes here mean classes that do one thing well.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is Atomic CSS?
&lt;/h3&gt;

&lt;p&gt;Atomic CSS is more of an architectural philosophy rather than one particular library or framework. Notably, Tailwind wasn’t the first on the atomic CSS scene. There are other libraries that adopt the atomic CSS pattern like &lt;a href="http://tachyons.io/" rel="noopener noreferrer"&gt;Tachyons&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;According to &lt;a href="https://css-tricks.com/author/johnpolacek/" rel="noopener noreferrer"&gt;John Polacek&lt;/a&gt; in his &lt;a href="https://css-tricks.com/lets-define-exactly-atomic-css/" rel="noopener noreferrer"&gt;article&lt;/a&gt;,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Atomic CSS is the approach to CSS architecture that favors small, single-purpose classes with names based on visual function.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Please note that Tailwind classes aren’t the same inline styles. The differences have best been captured elaborately in &lt;a href="https://frontstuff.io/in-defense-of-utility-first-css" rel="noopener noreferrer"&gt;this article&lt;/a&gt; by &lt;a href="https://twitter.com/frontstuff_io" rel="noopener noreferrer"&gt;Sarah Dayan&lt;/a&gt;. Rather than go through the reasons outlining differences, I’ll just give a scenario instead.&lt;/p&gt;

&lt;p&gt;Say you want a card profile component that appears in landscape on a widescreen with left-aligned text but portrait on a smaller screen with center-aligned text, and it also changes the background color, shadows, and opacity when hovered or focused. &lt;/p&gt;

&lt;p&gt;Can inline styles help you out there? Yeah, I didn’t think so.&lt;/p&gt;

&lt;h2&gt;
  
  
  My comparison
&lt;/h2&gt;

&lt;p&gt;As the title implies, the essence of this article is to give my take on the two frameworks and explain my thought process behind them.&lt;/p&gt;

&lt;p&gt;There are undeniable advantages for both Tailwind and Sass. Based on your preferences you’d place more weight on one over the other in certain instances. &lt;/p&gt;

&lt;p&gt;In all honesty, I initially started out with Sass. I loved it, it saved me from repetitive and cumbersome native CSS. But per my experience with both as well as recent updates, Tailwind has evolved to become my go-to CSS framework on most new projects. Here are my reasons:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Composability &amp;amp; Modularity
&lt;/h3&gt;

&lt;p&gt;With Sass, there has to be extra effort on the part of the developer to achieve a modular system in order to make CSS more manageable and robust. This can be done using different modular CSS methodologies like Object Oriented CSS (OOCSS) or Block, Element, and Modifier (BEM), etc. More on those &lt;a href="https://snipcart.com/blog/organize-css-modular-architecture" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This however is a given with Tailwind. Tailwind classes by their atomic nature are able to effectively build composable isolated components.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Naming
&lt;/h3&gt;

&lt;p&gt;I’m sure there are developers out there who pride themselves on being able to come up with clever and suitable names for CSS classes. I, am not one of those people.&lt;/p&gt;

&lt;p&gt;Let’s say you want to name a classes for a card that holds the card ads for a site. You might come up with,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="nc"&gt;.car&lt;/span&gt;&lt;span class="err"&gt;–&lt;/span&gt;&lt;span class="nt"&gt;card&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nc"&gt;...&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.car&lt;/span&gt;&lt;span class="err"&gt;–&lt;/span&gt;&lt;span class="nt"&gt;card&lt;/span&gt; &lt;span class="nc"&gt;.img&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nc"&gt;...&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.car--card&lt;/span&gt; &lt;span class="nc"&gt;.img&lt;/span&gt; &lt;span class="nt"&gt;img&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nc"&gt;...&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.other&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nc"&gt;...&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Further down the development line, you discover the same design is used for other ads on your app. This can become,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="nc"&gt;.ad&lt;/span&gt;&lt;span class="err"&gt;–&lt;/span&gt;&lt;span class="nt"&gt;card&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nc"&gt;...&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.ad--card&lt;/span&gt; &lt;span class="nc"&gt;.img&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nc"&gt;...&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.ad&lt;/span&gt;&lt;span class="err"&gt;–&lt;/span&gt;&lt;span class="nt"&gt;card&lt;/span&gt; &lt;span class="nc"&gt;.img&lt;/span&gt; &lt;span class="nt"&gt;img&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nc"&gt;...&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.other&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nc"&gt;...&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then later you discover that the same design is used for the card that show your app services. This it becomes,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="nc"&gt;.media&lt;/span&gt;&lt;span class="err"&gt;–&lt;/span&gt;&lt;span class="nt"&gt;-card&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nc"&gt;...&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.media--card&lt;/span&gt; &lt;span class="nc"&gt;.img&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nc"&gt;...&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.media&lt;/span&gt;&lt;span class="err"&gt;–&lt;/span&gt;&lt;span class="nt"&gt;card&lt;/span&gt; &lt;span class="nc"&gt;.img&lt;/span&gt; &lt;span class="nt"&gt;img&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nc"&gt;...&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.other&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nc"&gt;...&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🤦🏾‍♂️ Not the best of examples, but do you see my point?&lt;/p&gt;

&lt;p&gt;Tailwind takes the burden of naming off my shoulders by providing suitably named and well documented classes which can always be looked up whenever needed. They utility classes mean the same things wherever, whenever.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Responsiveness
&lt;/h3&gt;

&lt;p&gt;Tailwind pushes you to use best practices when developing. Notable it enforces the mobile-first approach, thereby forcing the developer to think of responsiveness right from the get-go. &lt;/p&gt;

&lt;p&gt;It encourages a robust approach that takes into consideration different screen sizes and orientations. This can also be easily extended in the tailwind config file.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Onboarding new developers
&lt;/h3&gt;

&lt;p&gt;It takes developers some time to get accustomed to any new codebase, even ones that have a familiar language. Specific decisions have to be understood enough to be followed. Essentially, newer developers have to interpret what someone else meant and whether their decisions were deliberate and contextual, or arbitrary and habitual.&lt;/p&gt;

&lt;p&gt;According to Daniel Terhorst-North in writing about &lt;a href="https://dannorth.net/2022/02/10/cupid-for-joyful-coding" rel="noopener noreferrer"&gt;CUPID&lt;/a&gt;,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The greatest programming trait is empathy; empathy for your users; empathy for support folks; empathy for future developers; any of whom may be future you. Writing “code that humans can understand” means writing code for someone else. This is what idiomatic code means.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;New developers can get accustomed to Tailwind classes in a short time. Although this would still be more than the time to learn Sass since, it is in appearance, still CSS.&lt;/p&gt;

&lt;p&gt;Sass provides more freedom in development however, this can lead to a problem of clarity. &lt;/p&gt;

&lt;h3&gt;
  
  
  5. Clarity
&lt;/h3&gt;

&lt;p&gt;The flexibility and freedom provided by Sass can serve as a blessing and a curse. Nesting selectors and media queries can hasten development for the author of a codebase but not so much for a maintainer that'd come in later.&lt;/p&gt;

&lt;p&gt;It's quite easy to create confusion due to nesting in Sass where elements can be selected from (almost) wherever. Granted, this is also possible with native CSS and isn't peculiar to Sass however it's an issue solved by atomic CSS. So, this is more of an architectural issue rather than an intrinsic one.&lt;/p&gt;

&lt;p&gt;I once wrote mixins using Sass like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="k"&gt;@mixin&lt;/span&gt; &lt;span class="nf"&gt;font-face&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$weight&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;500&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$style&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;normal&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$weight&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;font-style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$style&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Poppins&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;BR&lt;/span&gt; &lt;span class="n"&gt;Firma&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@mixin&lt;/span&gt; &lt;span class="nf"&gt;font-look&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$font-size&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$line-height&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$font-size&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;line-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$line-height&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@mixin&lt;/span&gt; &lt;span class="nf"&gt;font-look-mediaQuery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$font-size&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$line-height&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$screen-width&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;600px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="n"&gt;only&lt;/span&gt; &lt;span class="n"&gt;screen&lt;/span&gt; &lt;span class="nf"&gt;and&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max-width&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$screen-width&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$font-size&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;line-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$line-height&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.p-bigbold&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="cm"&gt;/* Paragraph Big Bold */&lt;/span&gt;
  &lt;span class="k"&gt;@include&lt;/span&gt; &lt;span class="nd"&gt;font-face&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;500&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;@include&lt;/span&gt; &lt;span class="nd"&gt;font-look&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="mi"&gt;.125rem&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="mi"&gt;.4375rem&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;@include&lt;/span&gt; &lt;span class="nd"&gt;font-look-mediaQuery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="mi"&gt;.875rem&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="mi"&gt;.125rem&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When I wrote this only God and I understood it, now only God does 😂&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Resilience
&lt;/h3&gt;

&lt;p&gt;Here I ask the question, How easy is it to mess up?&lt;/p&gt;

&lt;p&gt;Making changes feels safer. Sass/SCSS can be global (there’s such a thing as scoped CSS) and you never know what you might break when you make a change. Classes in your HTML are local, so you can change them without worrying about something else breaking.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Predictability &amp;amp;&amp;amp; Consistency
&lt;/h3&gt;

&lt;p&gt;Tailwind is fully deterministic. It does the same thing everywhere. Compared to Sass a component can be copied and pasted in a different and there’s a better chance it looks the same. With Sass, it really depends on the architecture. &lt;/p&gt;

&lt;p&gt;No need to fight specificity battles, I prefer the consistency of Tailwind.&lt;/p&gt;

&lt;h3&gt;
  
  
  8. Constraints
&lt;/h3&gt;

&lt;p&gt;Being able to follow a design system is a hallmark of a good frontend developer but in cases where there isn't a clear design, system Tailwind provides sane defaults that are invaluable.&lt;/p&gt;

&lt;p&gt;Tailwind's utility classes help you work within the constraints of a system instead of littering your stylesheets with arbitrary values. &lt;/p&gt;

&lt;p&gt;In practice, one way(my preferred way) of sticking to a design system is to define constants that hold the values of all different sizes, colours, fonts, and all that a design system entails. Then apply those constants wherever needed in the codebase.&lt;/p&gt;

&lt;p&gt;This is possible in both Sass, with the use of variables, and also tailwind with the use of custom classes. But without a doubt, Tailwind's tooling takes the cake.&lt;/p&gt;

&lt;h3&gt;
  
  
  9. Tooling
&lt;/h3&gt;

&lt;p&gt;On VScode (my IDE of choice) the IntelliSense provided when styling with Tailwind is second to none.&lt;/p&gt;

&lt;p&gt;I found Tailwind's syntax intuitive yet the tooling makes writing Tailwind even easier. In fact, I only got to know some CSS rules when I began writing Tailwind.&lt;/p&gt;

&lt;p&gt;Yes, I'm looking at you &lt;code&gt;whitespace-nowrap&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Concerns
&lt;/h2&gt;

&lt;p&gt;As with all things, there are demerits and trade-offs. Some of the ones I list here are per my use as at the time of writing. &lt;/p&gt;

&lt;p&gt;Notably, there are other concerns with Tailwind that have been handled by subsequent upgrades. I won't dwell much on those in the section below.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Breaking Constraints
&lt;/h3&gt;

&lt;p&gt;Tailwind is utility-first, not utility-only. Asides from the practice of just adding regular CSS or Sass styles alongside Tailwind classes, the maintainers of Tailwind provided a way to add in custom sizes, colours, etc directly in the Tailwind classes.&lt;/p&gt;

&lt;p&gt;This is possible thanks to the Tailwind JIT (Just In Time) compiler. Just like Sass's nesting feature, this is also a blessing and a curse.&lt;/p&gt;

&lt;p&gt;It helps in cases where the developer wants one-off dimensions that are not available in the default Tailwind classes and isn't worth creating custom classes for. But then it provides an avenue to keep using custom values all over the app.&lt;/p&gt;

&lt;p&gt;Although this is unlikely, you'd be surprised what you'd find in some codebases 😬&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Size
&lt;/h3&gt;

&lt;p&gt;Although Tailwind utilizes PostCSS to remove all unused styles, it's still larger in production than if Sass had been used. &lt;/p&gt;

&lt;p&gt;This actually isn't much of an issue since if your CSS is in the range of kilobytes there are far better ways to improve performance on your site. So, this isn't so serious but it was worth mentioning for the sake of being thorough.&lt;/p&gt;

&lt;p&gt;Also, keep in mind that Tailwind used to be massive in development but in recent upgrades, the JIT compiler has deployed in response to this. However, this has created a different problem which I elaborate on below.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Debugging
&lt;/h3&gt;

&lt;p&gt;Recent upgrades of the JIT compiler to Tailwind development have made debugging using the browser dev tools more difficult in some cases.&lt;/p&gt;

&lt;p&gt;This is due to the JIT compiler creating classes on the fly, therefore, removing the need to purge unused CSS classes since they were never created in the first place. &lt;/p&gt;

&lt;p&gt;However, because the classes are created on the fly any class not specified somewhere in the code doesn't exist and cannot be added ad hoc in the dev tools. This is needed sometimes to quickly see how a certain class affects the styles.&lt;/p&gt;

&lt;p&gt;This can become especially burdensome if there are several custom tailwind classes added to the config.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;There are tools to help with this though like Devtools for &lt;a href="https://devtoolsfortailwind.com/" rel="noopener noreferrer"&gt;Tailwind&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  4. Theming
&lt;/h3&gt;

&lt;p&gt;This might be more of a personal preference but I’m not for the &lt;code&gt;bg-white dark:bg-black&lt;/code&gt; syntax which is the default way of theming in Tailwind. Why have classes that do nothing half the time? What if I want more than two themes?&lt;/p&gt;

&lt;p&gt;I’d rather have variables that I can switch out at will. Another approach is to use custom classes that are toggled like the approach that &lt;a href="https://github.com/pacocoursey/next-themes" rel="noopener noreferrer"&gt;Next-themes&lt;/a&gt; takes. However, this is specific to NextJS.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;As a note, it’s not the tool but the craftsman that does good work. Tailwind provides benefits out of the box, but these can be opted out of following bad usage of the library.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Everything rises and falls on architecture.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In summary, I’ll advise choosing Tailwind in a new project as it presents sane defaults which help provide structure to an application.&lt;/p&gt;

&lt;p&gt;There are other alternatives to just Tailwind or Sass. The option of Styled-components is also a good one, which enables the use of Sass/SCSS syntax within its tagged templates. You can also use Tailwind in conjunction with Styled-components using a library like &lt;a href="https://github.com/ben-rogerson/twin.macro" rel="noopener noreferrer"&gt;Twin.macro&lt;/a&gt; or &lt;a href="https://twind.dev/" rel="noopener noreferrer"&gt;Twind&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For a holistic view of the opposition to Tailwind, you can read a different point of view &lt;a href="https://www.aleksandrhovhannisyan.com/blog/why-i-dont-like-tailwind-css/#4-tailwind-is-bloated" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I hope this article helps. &lt;/p&gt;

&lt;p&gt;Please share your thoughts and opinions in the comments section below.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://frontstuff.io/no-utility-classes-arent-the-same-as-inline-styles" rel="noopener noreferrer"&gt;https://frontstuff.io/no-utility-classes-arent-the-same-as-inline-styles&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://frontstuff.io/in-defense-of-utility-first-css" rel="noopener noreferrer"&gt;https://frontstuff.io/in-defense-of-utility-first-css&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://johnpolacek.github.io/the-case-for-atomic-css/" rel="noopener noreferrer"&gt;https://johnpolacek.github.io/the-case-for-atomic-css/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.codecademy.com/resources/blog/what-is-sass/" rel="noopener noreferrer"&gt;https://www.codecademy.com/resources/blog/what-is-sass/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://snipcart.com/blog/organize-css-modular-architecture" rel="noopener noreferrer"&gt;https://snipcart.com/blog/organize-css-modular-architecture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.swyx.io/why-tailwind/?ck_subscriber_id=1095223109" rel="noopener noreferrer"&gt;https://www.swyx.io/why-tailwind/?ck_subscriber_id=1095223109&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://css-tricks.com/lets-define-exactly-atomic-css/" rel="noopener noreferrer"&gt;https://css-tricks.com/lets-define-exactly-atomic-css/&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>tailwindcss</category>
      <category>sass</category>
      <category>styling</category>
      <category>css</category>
    </item>
    <item>
      <title>A Guide to Order: Setting up Prettier and Eslint with Husky, Lint-staged and Commitizen</title>
      <dc:creator>Folafunmi</dc:creator>
      <pubDate>Thu, 17 Feb 2022 15:30:23 +0000</pubDate>
      <link>https://forem.com/playfulprogramming/a-guide-to-order-setting-up-prettier-and-eslint-with-husky-lint-staged-and-commitzen-3dm1</link>
      <guid>https://forem.com/playfulprogramming/a-guide-to-order-setting-up-prettier-and-eslint-with-husky-lint-staged-and-commitzen-3dm1</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TLDR:&lt;/strong&gt; To save yourself a headache, use coding standards and become more efficient by automating your development workflow.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;Have you ever had to code review a PR that has 2000+ changes, when the actual code change was less than 15 lines? I have and it’s quite annoying.&lt;/p&gt;

&lt;p&gt;When we write code it is to the end that it’s understood by other developers and also your future self. As such we find value in guiding principles and conventions by which we’re able to develop in a consistent manner. This is the very reason for coding standards.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Order over chaos.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Coding standards are best-practices guides that developers follow in order to write code in a predictable and consistent manner. Basically, this makes it easier for the team to maintain and extend an existing codebase.&lt;/p&gt;

&lt;p&gt;Engineers at their core tend to prefer automation over manual processes. Being willing to spend hours automating a task that’d take just a few minutes of manual labour. In like manner, there’s the obvious benefit of automating the enforcement of coding standards in a project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Yes, it’ll fix your errors without additional effort!!! 🎉&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This write-up contains explanations as well as a tutorial on how this can be done using Husky, Lint-staged, Eslint, Prettier, and Commitizen.&lt;/p&gt;

&lt;h2&gt;
  
  
  Learning outcome
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Understand what coding standards are&lt;/li&gt;
&lt;li&gt;Understand the advantages of coding standards&lt;/li&gt;
&lt;li&gt;Understand git hooks&lt;/li&gt;
&lt;li&gt;Setup git hooks with husky and lint-staged&lt;/li&gt;
&lt;li&gt;Configure Eslint, Prettier, and Commitizen&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Node &amp;gt;= v14&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;NB:&lt;/strong&gt; As usual, I lean towards a thorough approach to learning and understanding, therefore I go through the explanations first outlining the benefits and answering why we need to set standards for every project in an organization.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Alternatively, if you’d rather just know how to set up the tools don’t worry I’ve got you covered. You can go directly to the tutorial section here&lt;/p&gt;

&lt;h2&gt;
  
  
  The what, why, and how of coding standards?
&lt;/h2&gt;

&lt;p&gt;Coding standards are a set of guidelines that recommend programming styles, practices, and methods for a given program.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why do we need them?&lt;/strong&gt; Because everyone writes code differently which is usually fine until you have to work with someone else's code.&lt;/p&gt;

&lt;p&gt;In development, I generally go by the maxim:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Prefer structure and consistency over style and comfort.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This presents benefits for every developer that’s working on and will work on the project.&lt;/p&gt;

&lt;h3&gt;
  
  
  Benefits of coding standards
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;It gives a uniform appearance to the codes written by different engineers.&lt;/li&gt;
&lt;li&gt;It improves the readability and maintainability of the codebase and it reduces complexity also.&lt;/li&gt;
&lt;li&gt;It allows catching of errors in their infancy&lt;/li&gt;
&lt;li&gt;It helps in code reuse and helps to detect errors easily.&lt;/li&gt;
&lt;li&gt;It promotes sound programming practices and increases the efficiency of programmers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is general aids developer productivity and speeds up work. It reduces the guessing game and revisions that newer developers have to go through when making contributions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Style guide
&lt;/h3&gt;

&lt;p&gt;A style guide contains general rules about “how to write” code. This usually contains fine-grained instructions on how code should appear. These would provide guidelines for how the code should look, clearly stating &lt;a href="https://en.wikipedia.org/wiki/Anti-pattern" rel="noopener noreferrer"&gt;anti-patterns&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To quote &lt;a href="https://medium.com/docon/airbnb-javascript-style-guide-key-takeaways-ffd0370c053" rel="noopener noreferrer"&gt;an article&lt;/a&gt; on the topic,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“All code in any code-base should look like a single person typed it, no matter how many people contributed.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Typical factors considered when choosing a style guide include:&lt;br&gt;
Indentation: tabs or spaces, indent width&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Bracket placement&lt;/li&gt;
&lt;li&gt;Quotes to use&lt;/li&gt;
&lt;li&gt;Spacing&lt;/li&gt;
&lt;li&gt;Ordering&lt;/li&gt;
&lt;li&gt;Comment style and the use of documentary comments&lt;/li&gt;
&lt;li&gt;Variable, class, and file naming conventions&lt;/li&gt;
&lt;li&gt;Statement style and best practices of their usage&lt;/li&gt;
&lt;li&gt;File organization&lt;/li&gt;
&lt;li&gt;Declaration of classes and interfaces&lt;/li&gt;
&lt;li&gt;Exception handling&lt;/li&gt;
&lt;li&gt;Import and export types&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, &lt;a href="https://airbnb.io/javascript/react/" rel="noopener noreferrer"&gt;Airbnb’s style guide for React&lt;/a&gt; gives a perfect picture of the expectations of a style guide.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fui5vsooytjfat4ox10pk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fui5vsooytjfat4ox10pk.png" alt="Airbnb style guide 1" width="800" height="262"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnsmb75minqsychoieeab.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnsmb75minqsychoieeab.png" alt="Airbnb style guide 2" width="800" height="282"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;More examples of coding standards can be found &lt;a href="https://github.com/housecricket/Coding-Conventions" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In practice, it’s important that all these have to be chosen by the team to ensure the standards fit the needs of the project and the developers involved. Coding standards for each team are different as such they have to be decided appropriately. In the end, it’s these developers as well as those that would come who will maintain the codebase. Therefore, they have to be considered when deciding on coding standards.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Suggestion:&lt;/strong&gt; Call a meeting with the dev team where coding standards are explicitly discussed and agreed upon.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Then, the golden question that this article aims to answer is, &lt;strong&gt;how can I enforce this in my codebase?&lt;/strong&gt; 🤔&lt;/p&gt;
&lt;h3&gt;
  
  
  Linting
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Lint_%28software%29" rel="noopener noreferrer"&gt;Linting&lt;/a&gt; is the process of using a tool to analyzes source code to flag programming errors, bugs, stylistic errors, and suspicious constructs. This is done using a &lt;strong&gt;Linter&lt;/strong&gt; or &lt;strong&gt;Lint tool&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The most popular amongst the lint tools is &lt;a href="https://eslint.org/" rel="noopener noreferrer"&gt;Eslint&lt;/a&gt;. According to the docs, &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;ESLint is a tool for identifying and reporting on patterns found in ECMAScript/JavaScript code, with the goal of making code more consistent and avoiding bugs.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Can be installed using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;eslint &lt;span class="nt"&gt;--save-dev&lt;/span&gt;

&lt;span class="c"&gt;# or&lt;/span&gt;

yarn add eslint &lt;span class="nt"&gt;--dev&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To set up a config file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm init @eslint/config

&lt;span class="c"&gt;# or&lt;/span&gt;

yarn create @eslint/config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will create an &lt;code&gt;.eslintrc.{js,yml,json}&lt;/code&gt; file in your directory. In it you’d find something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"rules"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"semi"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"error"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"always"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"quotes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"error"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"double"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These rules guide Eslint when it scans your codebase to know what conventions you’ve specified to follow. &lt;/p&gt;

&lt;p&gt;Your &lt;code&gt;.eslintrc.{js,yml,json}&lt;/code&gt; configuration file will also include the line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"extends"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"eslint:recommended"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This provides some (default standards](&lt;a href="https://eslint.org/docs/rules" rel="noopener noreferrer"&gt;https://eslint.org/docs/rules&lt;/a&gt;) (all of the rules marked "✓") from Eslint. These can also be extended using Eslint’s rich plugin system. &lt;/p&gt;

&lt;p&gt;You can create and publish your own config, and can also install plugins from other creators from NPM. Some notable ones include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.npmjs.com/package/eslint-config-airbnb" rel="noopener noreferrer"&gt;Airbnb’s eslint config&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/google/eslint-config-google" rel="noopener noreferrer"&gt;Google’s eslint config&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;An alternative linter is &lt;a href="https://jshint.com/" rel="noopener noreferrer"&gt;JShint&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Formatting
&lt;/h3&gt;

&lt;p&gt;Prettier is an opinionated code formatter with support for various languages. It ensures that all outputted code conforms to a consistent style. Prettier takes your code and reprints it from scratch by taking your configuration into account. You can learn more &lt;a href="https://www.youtube.com/watch?v=hkfBvpEfWdA" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The docs present extensively the &lt;a href="https://prettier.io/docs/en/why-prettier.html" rel="noopener noreferrer"&gt;benefits&lt;/a&gt; of using Prettier as a code formatter. Some of which include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Building and enforcing a style guide&lt;/li&gt;
&lt;li&gt;Helping Newcomers&lt;/li&gt;
&lt;li&gt;Easy to adopt&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Can be installed using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;prettier &lt;span class="nt"&gt;--save-dev&lt;/span&gt;

&lt;span class="c"&gt;# or&lt;/span&gt;

yarn add prettier &lt;span class="nt"&gt;--dev&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Differences between linters and formatters
&lt;/h3&gt;

&lt;p&gt;Linters analyze your codebase to catch errors and suggest best practices ( involving the use of the abstract syntax tree) while formatters fix code style. Linters should deal with tasks like function complexity, syntax improvements, etc while formatter should deal with tasks like spacing, line wraps, comments, etc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Linters can be used as formatters, but they are not the best fit for those classes of tasks.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Prettier documentation makes reference to (formatters vs linters](&lt;a href="https://prettier.io/docs/en/comparison.html#how-does-it-compare-to-eslinttslintstylelint-etc" rel="noopener noreferrer"&gt;https://prettier.io/docs/en/comparison.html#how-does-it-compare-to-eslinttslintstylelint-etc&lt;/a&gt;), stating to:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Use Prettier for formatting and linters for catching bugs!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Both do their job well as such should be used together.&lt;/p&gt;

&lt;p&gt;However, there’s a known problem when using both Eslint and Prettier. A good approach is to run prettier first and then Eslint. There, however, exists a simpler solution. Enter &lt;a href="https://github.com/sheerun/prettier-standard" rel="noopener noreferrer"&gt;prettier-standard&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/sheerun/prettier-standard" rel="noopener noreferrer"&gt;Prettier-standard&lt;/a&gt; helps to format with prettier (actually &lt;a href="https://github.com/brodybits/prettierx" rel="noopener noreferrer"&gt;prettierx&lt;/a&gt;) and lints with &lt;a href="https://eslint.org/" rel="noopener noreferrer"&gt;eslint&lt;/a&gt; preconfigured with &lt;a href="https://github.com/standard/standard" rel="noopener noreferrer"&gt;standard&lt;/a&gt; rules. No eslint config has to be set.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; On VScode, an extension that can make this experience better is &lt;a href="https://marketplace.visualstudio.com/items?itemName=usernamehw.errorlens" rel="noopener noreferrer"&gt;Error lens&lt;/a&gt;. This highlights sections of the codebase that require linting or formatting thereby creating a better experience for the developer.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyctmdkvcmvz7ylyfw7d3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyctmdkvcmvz7ylyfw7d3.png" alt="error lens" width="800" height="92"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Git hooks
&lt;/h3&gt;

&lt;p&gt;Git hooks are scripts that Git executes before or after events such as commit, push, and pull. They can be used to alter internal behavior and receive notifications when certain events occur in a repository. Git hooks are built into Git so there’s no need to download anything. These Git hooks run locally.&lt;/p&gt;

&lt;p&gt;Some example hook scripts include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;pre-commit: Can be used to check that the commit message conforms to convention.&lt;/li&gt;
&lt;li&gt;post-commit: Can be used to email team members of a new commit.&lt;/li&gt;
&lt;li&gt;post-merge: Can be used to install new dependencies&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A comprehensive list of Git hooks can be found &lt;a href="https://githooks.com/" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5ds0r8m2fjwyamj2qzy1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5ds0r8m2fjwyamj2qzy1.png" alt="Hook execution timeline" width="800" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hooks are regular scripts that reside in the .git/hooks directory of your project. This makes them easy to install and customize. They plug into the entire development life cycle. We now know how to perform customizable actions at every stage in the commit creation process, therefore can greatly increase developer productivity.&lt;/p&gt;

&lt;p&gt;A more elaborate explanation of the hooks overview, concept, and scope can be found &lt;a href="https://www.atlassian.com/git/tutorials/git-hooks" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Set up Husky and Lint-staged
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Install husky
&lt;/h3&gt;

&lt;p&gt;First, we have to initialize husky. We do this using &lt;code&gt;npx&lt;/code&gt;,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx husky-init &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm i

&lt;span class="c"&gt;#Or&lt;/span&gt;

npx husky-init &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; yarn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This would edit the package.json file by adding the husky dev dependency and the script,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="s2"&gt;"scripts"&lt;/span&gt;:&lt;span class="o"&gt;{&lt;/span&gt;
…
&lt;span class="s2"&gt;"prepare"&lt;/span&gt;: &lt;span class="s2"&gt;"husky install"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This helps to install husky on other devices.&lt;/p&gt;

&lt;p&gt;It also creates a &lt;code&gt;.husky&lt;/code&gt; folder in the root directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;|-- .husky/
   |-- _/
       |-- husky.sh
   |-- .gitignore
   |-- pre-commit

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The pre-commit file contains a default script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/sh&lt;/span&gt;
&lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;dirname&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$0&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;/_/husky.sh"&lt;/span&gt;

npm &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This script contains commands that’d run just before a commit is made. Let’s edit this to run type checks and test scripts before a commit is made.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Omit the typescript portions of the script if you’re using Javascript&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/sh&lt;/span&gt;
&lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;dirname&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$0&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;/_/husky.sh"&lt;/span&gt;

npm run tsc
npm &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And we add the script to the package.json&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;…&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"tsc"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tsc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"prepare"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"husky install"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But there’s a problem. This would run the test files and type checks every time we change anything at all. To solve this we use lint-staged.&lt;br&gt;
 ### Install Lint-staged along with Prettier and Eslint&lt;/p&gt;

&lt;p&gt;Install lint-staged, prettier and eslint using,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i &lt;span class="nt"&gt;--save-dev&lt;/span&gt; lint-staged prettier eslint 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lint-staged allows us to run scripts &lt;strong&gt;only when&lt;/strong&gt; certain files are about to be committed. Let’s edit our package.json to reflect this,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;…&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;“lint”:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;“eslint&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;--fix”&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"tsc"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tsc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"prepare"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"husky install"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;…&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"husky"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"hooks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"pre-commit"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"lint-staged"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"lint-staged"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"**/*.{js,jsx,ts,tsx}"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="s2"&gt;"npm run lint"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;“npm&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;run&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;test&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;--watchAll=&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;--findRelatedTests&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;--bail”&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"**/*.{json,css,md}"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"prettier --write"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Please play around with the flags to obtain the suited result.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We can then go back to edit the pre-commit file,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/sh&lt;/span&gt;
&lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;dirname&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$0&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;/_/husky.sh"&lt;/span&gt;

npm run tsc
npx lint-staged
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can then add &lt;code&gt;.eslint.rc&lt;/code&gt;, &lt;code&gt;.eslintignore&lt;/code&gt;, &lt;code&gt;.prettier.rc&lt;/code&gt; and &lt;code&gt;.prettierignore&lt;/code&gt; as you see fit.&lt;/p&gt;

&lt;p&gt;Now, when a commit is to be made lint-sage would run the type checker, eslint and prettier.&lt;/p&gt;

&lt;h3&gt;
  
  
  Set up a commit message hook and Commitizen
&lt;/h3&gt;

&lt;p&gt;The &lt;a href="https://www.conventionalcommits.org/en/v1.0.0/" rel="noopener noreferrer"&gt;Conventional Commits&lt;/a&gt; specification is a lightweight convention on top of commit messages. It provides an easy set of rules for creating an explicit commit history.&lt;/p&gt;

&lt;p&gt;We can create a hook that’d check if the commit message is according to the conventional commit standard.&lt;/p&gt;

&lt;p&gt;To add a hook to check the commit message, run the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx husky add .husky/commit-msg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then paste in the script below,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/sh&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-1&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-qE&lt;/span&gt; &lt;span class="s2"&gt;"^(feat|fix|chore|docs|test|style|refactor|perf|build|ci|revert)(&lt;/span&gt;&lt;span class="se"&gt;\(&lt;/span&gt;&lt;span class="s2"&gt;.+?&lt;/span&gt;&lt;span class="se"&gt;\)&lt;/span&gt;&lt;span class="s2"&gt;)?: .{1,}$"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Aborting commit. Your commit message is invalid."&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&amp;amp;2
    &lt;span class="nb"&gt;exit &lt;/span&gt;1
&lt;span class="k"&gt;fi
if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-1&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-qE&lt;/span&gt; &lt;span class="s2"&gt;"^.{1,88}$"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Aborting commit. Your commit message is too long."&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&amp;amp;2
    &lt;span class="nb"&gt;exit &lt;/span&gt;1
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In order to simplify the process of making a commit according to conventional commit standards, you can install &lt;a href="https://commitizen-tools.github.io/commitizen/" rel="noopener noreferrer"&gt;Commitizen&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Install commitizen as a dev dependency,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i –save-dev commitizen
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then initialize commitizen,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;commitizen init cz-conventional-changelog &lt;span class="nt"&gt;--save&lt;/span&gt; &lt;span class="nt"&gt;--force&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This would provide a setup such that when you make a commit(after &lt;code&gt;git add …&lt;/code&gt; of course) using the command,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git cz
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You get this,&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F87gbqo1eksgipnzjsztb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F87gbqo1eksgipnzjsztb.png" alt="Commitizen cli" width="800" height="284"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now you’ve set up an automated workflow with husky, lint-staged, eslint, prettier and commitizen.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This implementation can be extended using &lt;a href="https://www.npmjs.com/package/dependency-cruiser" rel="noopener noreferrer"&gt;dependency cruiser&lt;/a&gt; to lock down certain dependencies from being used across the codebase. This is however quite optional and should be adopted as the need demands.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Caveats
&lt;/h2&gt;

&lt;p&gt;There are some caveats to this approach though.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Might be overkill for small apps&lt;/li&gt;
&lt;li&gt;Doesn’t eliminate the need for proper communication&lt;/li&gt;
&lt;li&gt;Not a replacement for CI&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Compliance with coding standards leads to more maintainable software and a team that works well better and ships faster. This is as a result of less back and forth on pull requests.&lt;/p&gt;

&lt;p&gt;A &lt;a href="https://www.researchgate.net/publication/328912784_The_Benefits_of_the_Coding_Standards_Enforcement_and_its_Impact_on_the_Developers_Coding_Behaviour-A_Case_Study_on_Two_Small_Projects" rel="noopener noreferrer"&gt;research article&lt;/a&gt; that studied two small projects even shows a dropping error rate when coding standards are adopted.&lt;/p&gt;

&lt;p&gt;Its authors' quote,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The dropping of error trends indicates that as developers align  with  the  coding  standard,  there  will  be  less  fault corrections,  hence  fewer  probability  to  new  faults. Nevetheless  although  less,  developers  will  be  making errors  in  any  circumstances,  which  justifies  the  coding standard check step in  the software development process. Another thing that  is evident through this research is that the  use  of  checking  tools  in  the  implementation  step mitigates the errors in the code checking step.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The adoption of coding standards can lead to better performance from the team generally as well as boost individual performance and growth. It provides a focus on reliability, security, and structure.&lt;/p&gt;

&lt;p&gt;Consequently, it dampens individual coding style yet I argue that priority should be placed on &lt;strong&gt;structure over style and consistency over comfort&lt;/strong&gt;. In my view, its benefits far outweigh its cost.&lt;/p&gt;

&lt;p&gt;Hope this article helps.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=oWty0Nw1ydk&amp;amp;t=486s&amp;amp;ab_channel=LeighHalliday" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=oWty0Nw1ydk&amp;amp;t=486s&amp;amp;ab_channel=LeighHalliday&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=jNxDNoYEGVU&amp;amp;t=1220s&amp;amp;ab_channel=LeoRoese" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=jNxDNoYEGVU&amp;amp;t=1220s&amp;amp;ab_channel=LeoRoese&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://githooks.com/" rel="noopener noreferrer"&gt;https://githooks.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/aitemr/awesome-git-hooks" rel="noopener noreferrer"&gt;https://github.com/aitemr/awesome-git-hooks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.researchgate.net/publication/328912784_The_Benefits_of_the_Coding_Standards_Enforcement_and_its_Impact_on_the_Developers_Coding_Behaviour-A_Case_Study_on_Two_Small_Projects" rel="noopener noreferrer"&gt;https://www.researchgate.net/publication/328912784_The_Benefits_of_the_Coding_Standards_Enforcement_and_its_Impact_on_the_Developers_Coding_Behaviour-A_Case_Study_on_Two_Small_Projects&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/docon/airbnb-javascript-style-guide-key-takeaways-ffd0370c053" rel="noopener noreferrer"&gt;https://medium.com/docon/airbnb-javascript-style-guide-key-takeaways-ffd0370c053&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://taiyr.me/what-is-the-difference-between-code-linters-and-formatters" rel="noopener noreferrer"&gt;https://taiyr.me/what-is-the-difference-between-code-linters-and-formatters&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Everybody cooks beans! Get good at debugging!</title>
      <dc:creator>Folafunmi</dc:creator>
      <pubDate>Thu, 10 Feb 2022 10:50:19 +0000</pubDate>
      <link>https://forem.com/playfulprogramming/everybody-cooks-beans-get-good-at-debugging-1l24</link>
      <guid>https://forem.com/playfulprogramming/everybody-cooks-beans-get-good-at-debugging-1l24</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TLDR:&lt;/strong&gt; Inevitably, you will create bugs. But can you debug it effectively? That’s what will matter.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Different organizations have their jargon. One I’ve picked up, stemming from my &lt;a href="https://segsalerty.com/" rel="noopener noreferrer"&gt;Engineering Manager&lt;/a&gt; is &lt;strong&gt;"Everybody cooks beans"&lt;/strong&gt;, which aims to communicate that everybody makes mistakes.&lt;/p&gt;

&lt;p&gt;This statement hopes to present a mentality that as much as we all want to do good work, mistakes are inevitable. Although his focus is on software engineering, it isn’t exclusive to the field. An adventure into any field presents opportunities to make mistakes. And it's in those mistakes that learning happens.&lt;/p&gt;

&lt;p&gt;Software engineering christened the term "bugs" to refer to unintended behaviors from a particular program. "Unintended" is the keyword here, as software essentially acts as designed not as intended. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Code doesn’t lie.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As software engineers, our role is to convert intention into code using syntax from a myriad of languages. This skill of delivering precise instructions to a computer to perform tasks comes with a responsibility to translate intention into instructions. It doesn't take long to realize that most of your work as a software engineer is to make the program behave as it's supposed to rather than as it is😅&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Precise instructions create features, the alternative produces bugs.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This isn't always the case as some faults in a program might impact performance but not obstruct function.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhybjfw47ubswge9sknag.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhybjfw47ubswge9sknag.jpeg" alt="broken pipe" width="500" height="781"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;NB: I don’t attempt to distinguish between bugs and errors. In my view, the disparity between the two, if any, wouldn’t significantly impact the focus of this article. As such I use the terms &lt;strong&gt;bugs&lt;/strong&gt; and &lt;strong&gt;errors&lt;/strong&gt; interchangeably.&lt;/p&gt;

&lt;p&gt;Some common types of bugs/errors can be found &lt;a href="https://siderlabs.com/blog/11-types-of-software-bugs/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As software engineering grows and as software becomes an interconnected network of services, the surface area for bugs to exist has only widened.&lt;/p&gt;

&lt;p&gt;Debugging which is analogous to troubleshooting is the process that involves identifying a problem, isolating the source of the problem, and then either correcting the problem or determining a way to work around it. &lt;/p&gt;

&lt;p&gt;The discipline to traverse multiple factors to narrow down issues to get at a root cause stands as one of the most important skills a developer can have.&lt;/p&gt;

&lt;p&gt;The skill to debug software, therefore, isn't an add-on, it's a must-have.&lt;/p&gt;

&lt;p&gt;Debugging your own software has been described as being a detective in your own crime.&lt;/p&gt;

&lt;p&gt;Even the most experienced and skilled developers are susceptible to committing crimes of their own. The only difference exists in that, through time, they have sharpened their detective skills to more quickly figure out the culprit.&lt;/p&gt;

&lt;p&gt;Some of the most advanced organizations still fall prey to bugs leading to an inability to dispense their services. A common term used in situations such as these is "outage".&lt;/p&gt;

&lt;p&gt;These can be caused by internal or external factors. The interconnectivity of services testifies to the inevitability of bugs/errors per time. Even the likes of &lt;a href="https://hacks.mozilla.org/2022/02/retrospective-and-technical-details-on-the-recent-firefox-outage/" rel="noopener noreferrer"&gt;Mozilla&lt;/a&gt;, &lt;a href="https://web.archive.org/web/20211016040522/https://blog.cloudflare.com/cloudflare-outage-on-july-17-2020/" rel="noopener noreferrer"&gt;Cloudflare&lt;/a&gt; and &lt;a href="https://aws.amazon.com/message/12721/" rel="noopener noreferrer"&gt;AWS&lt;/a&gt; suffer outages. Usually, these are followed up by a &lt;a href="https://www.freecodecamp.org/news/what-is-a-software-post-mortem/" rel="noopener noreferrer"&gt;post-mortem&lt;/a&gt; which, essentially, is an analysis of the error with the benefit of hindsight.&lt;/p&gt;

&lt;p&gt;A comprehensive list of post-mortems can be found &lt;a href="https://github.com/danluu/post-mortems" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Challenges of debugging
&lt;/h2&gt;

&lt;p&gt;Compared to other aspects of software engineering there aren't as many well-documented resources on debugging. Worse is that developers often have an informal introduction to debugging, which is in the instance of a fault.&lt;/p&gt;

&lt;p&gt;Quite often, debugging happens under pressure and with little information to go on. Failures are often sporadic. Engineers are short on time and have to come up with a solution yesterday. Managers check-in within intervals. In worse cases there's panic, and everyone eagerly waits to hear "we fixed it".&lt;/p&gt;

&lt;p&gt;In such cases, it's important for the developer to follow a systematic approach. This entails repeatable steps that follow a predefined pattern. Following a systematic approach will help other developers too, should they encounter a similar bug.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdx6d406b8pq2qmvuvvxi.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdx6d406b8pq2qmvuvvxi.jpeg" alt="brute force" width="474" height="537"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Methodology
&lt;/h2&gt;

&lt;p&gt;In no manner do I consider myself an expert at debugging but I have developed repeatable patterns that have helped me in tracking down and fixing bugs. It’s my opinion on debugging which bears semblance to the scientific method.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: The majority of my experience is as a front-end developer in the webspace as such my examples would be given in that regard. However, I do believe that this approach would benefit other aspects of software engineering. More so, I'm aware that there are caveats in peculiar cases for which one or more steps in my method would not apply but &lt;strong&gt;my focus is on the rule and not the exceptions&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fycdv0dzlrbaaf259x3j8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fycdv0dzlrbaaf259x3j8.png" alt="A flowchart showing systematic debugging methodology" width="800" height="1007"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Reproduce the error
&lt;/h3&gt;

&lt;p&gt;This is a critical step and &lt;strong&gt;must not&lt;/strong&gt; be overlooked. You have to be sure that a particular sequence of steps or a certain scenario causes the bug and document it. You’d need it later. &lt;/p&gt;

&lt;p&gt;Go ahead to detail the bug using the following guide:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Describe the bug clearly&lt;/li&gt;
&lt;li&gt;Give a detailed account of the environment&lt;/li&gt;
&lt;li&gt;Outline precise steps to reproduce the bug&lt;/li&gt;
&lt;li&gt;Include attachments for clarity&lt;/li&gt;
&lt;li&gt;This is called bug reporting and an elaborate guide to writing good bug reports can be found &lt;a href="https://www.jotform.com/blog/bug-report/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you lack sufficient information about the bug, try to get some before you forge ahead, otherwise, you’d be flying blind.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A bug that cannot be reproduced cannot be said to have been fixed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There might be instances where reproducing the error is impossible or painfully difficult. There are measures to put in place to aid debugging in such cases and would be discussed under the developments in debugging section. For now, move on to the next step.&lt;/p&gt;

&lt;p&gt;For web developers, a platform like &lt;a href="https://codesandbox.io/" rel="noopener noreferrer"&gt;Code Sandbox&lt;/a&gt; is invaluable in debugging as it provides an isolated environment where the error can be reproduced reliably. No longer would we be haunted by statements like "it fails on my computer".&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Follow the evidence
&lt;/h3&gt;

&lt;p&gt;Analyze the call stack and error message. Different programming languages provide a means to access the call stack in the error object. This provides a stack trace that contains information related to the failure.&lt;/p&gt;

&lt;p&gt;Usually, the stack trace contains the following information:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;file name where the error occurred&lt;/li&gt;
&lt;li&gt;line number in the file where the error occurred&lt;/li&gt;
&lt;li&gt;the column number in the file where the error occurred&lt;/li&gt;
&lt;li&gt;function/class method name in which error occurred&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Going through the logs is vital as stack traces can provide insight into the origin and type of the error.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It’d also be beneficial to know how to use Google. Query structure and google docs help a lot in narrowing down searches. You can learn that &lt;a href="https://www.lifehack.org/articles/technology/20-tips-use-google-search-efficiently.html" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If need be, go through documentation and test files. This should become second nature to software engineers with the inevitability of third-party software. Once, I had to figure out the functionality of a library by going through their tests because the documentation sucked.&lt;/p&gt;

&lt;p&gt;In the case of third-party software, there'd have been other developers who've encountered this error. If so, you can short-circuit the process and skip to step 4.&lt;/p&gt;

&lt;p&gt;However, if you're the unlucky fellow 😅 that encounters the issue first proceed to step 3.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Develop a hypothesis
&lt;/h3&gt;

&lt;p&gt;At this juncture, based on the knowledge of the systems at play as well as their interconnections, you should make an educated guess.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/acemarke" rel="noopener noreferrer"&gt;Mark Erikson&lt;/a&gt;, a Redux maintainer, outlines this as having a plan,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Understand how the code should behave first. Look at the actual behavior. You can probably make educated guesses for where things are diverging. Focus on those areas. Don't randomly tweak. Change one thing at a time and compare results.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Experience definitely helps here, but even if you’re new to the situation there’s no need to fear. Come up with an explanation according to what you currently understand. You can always revise it later. &lt;/p&gt;

&lt;p&gt;This hypothesis can come from colleagues as well as from Q&amp;amp;A forums like stack overflow as well as search results from Google or tutorials from Youtube.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Test the hypothesis
&lt;/h3&gt;

&lt;p&gt;It is possible, based on prior knowledge, to jump right through by guessing the cause of failure. However, I have seen that this isn't always possible. As such any proposed solution should be applied and then validated against the steps in the bug report.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Do not be a sucker for punishment! First, try the suggestions from your search results and Stack Overflow. Especially for third-party software.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Step 5: Take action
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Treat the disease and not the symptoms.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here you can choose to refined the method of resolving the bug. This can be to refine your hypothesis based on info gotten from testing the hypothesis. &lt;/p&gt;

&lt;p&gt;Check if the bug is a stand-alone issue or if it’s a result of underlying problems in the codebase or configuration. If you’re satisfied with the outcome of testing the hypothesis then you can commit to the fix (for example to make a pull request).&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 6: Test and Observe
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;“Never allow the same bug to bite you twice.” - Steve Maguire&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There's the need to be watchful as a supposed fix might introduce new bugs. Therefore, &lt;a href="https://www.katalon.com/resources-center/blog/regression-testing/" rel="noopener noreferrer"&gt;regressive testing&lt;/a&gt; should be carried out to determine if the bug really had been squashed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1z9bmky2gqk3lj82m788.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1z9bmky2gqk3lj82m788.jpeg" alt="Regression test" width="597" height="377"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Regression testing is a software testing practice that ensures an application still functions as expected after any code changes, updates, or improvements.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Herein lies the importance of Step 1: Reproducing the bug. You’d have no way of knowing if truly the bug has been fixed if you didn’t have procedures that cause the bug to surface.&lt;/p&gt;

&lt;p&gt;Test with those procedures and others to confirm, and if you discover another bug, &lt;br&gt;
Great! It means you caught a bug before it went into production.&lt;/p&gt;

&lt;p&gt;Testing isn't debugging. Testing here starts with a known condition (testing whether the image shows up) while debugging starts with an unknown condition (why is the image not showing up). Another difference, although somewhat comical, is that managers would accept a test that yields no fault but not a debugging effort that yielded no solution 😅&lt;/p&gt;
&lt;h2&gt;
  
  
  A case study
&lt;/h2&gt;

&lt;p&gt;Let’s consider a scenario where this methodology was followed. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;NB: My example might seem trivial but the aim was to details a scenario where the methodology could be seen in action. Also to point out that bugs/errors might surface from little things.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I recently encountered a bug/error, where the Twitter preview image wasn’t showing up for a specific page of a website.&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 1: Reproduce the error
&lt;/h3&gt;

&lt;p&gt;The bug report can be outlined as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Description:&lt;/strong&gt; Twitter preview image not showing up for landing page route alone.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Environment:&lt;/strong&gt; Twitter web and mobile&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Steps to reproduce:&lt;/strong&gt; Tweet *** link, the preview doesn’t show up.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Attachments:&lt;/strong&gt; (excluded for this example)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Step 2: Follow the evidence
&lt;/h3&gt;

&lt;p&gt;Firstly, I tried to validate the card preview and got an error.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwiye8p3ppi0o4c7aaji8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwiye8p3ppi0o4c7aaji8.png" alt="Twitter card validator error" width="800" height="492"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;ERROR: Fetching the page failed because the response is too large.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  Step 3: Develop a hypothesis
&lt;/h3&gt;

&lt;p&gt;On seeing the words “response was too large”, I checked to confirm the resolution of the image was indeed hosted on the site, it was about 1200x1200. Hmmm…seems large🤔&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hypothesis:&lt;/strong&gt; The image is too large and twitter’s bot isn’t able to fetch it.&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 4: Test the hypothesis
&lt;/h3&gt;

&lt;p&gt;I requested for an image with smaller dimension and waited.&lt;/p&gt;

&lt;p&gt;While waiting I happened to run across the description and noted that only one page had this issue and the same image had been used for the others. I checked the docs for Twitter’s limit on the dimension of a preview image, it was 4096x4096.&lt;/p&gt;

&lt;p&gt;What? So the image fits within the limit?! 🤦🏾‍♂️&lt;/p&gt;

&lt;p&gt;I didn’t bother checking if it’d be fixed in Step 5, it wouldn’t.&lt;/p&gt;
&lt;h3&gt;
  
  
  Back to Step 3: Develop a hypothesis
&lt;/h3&gt;

&lt;p&gt;I read the error message again.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;ERROR: Fetching the page failed because the response is too large.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Oh, the &lt;em&gt;page&lt;/em&gt; itself is too large?&lt;/p&gt;

&lt;p&gt;I checked the documentation and found that the limit for page size is 2MB. I thought that was ridiculous. No way was the page document over 2MB. However, I check the network tab for the response.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkc2hkwyy5sfjbbfb8pas.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkc2hkwyy5sfjbbfb8pas.png" alt="Network tab" width="800" height="654"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What?! 2.5MB?! How’s that possible, it’s a document?!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The site was built using React so I couldn’t check the file size directly. I had to see what the Twitter bot saw, so I went to the command line.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frj5xxi60a5xddk1vw7mo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frj5xxi60a5xddk1vw7mo.png" alt="Command line test 1" width="800" height="194"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Wow, so the document really was 2.5MB. How so?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I went snooping around the page source (pretty printed of course) but I wasn’t sure what I was looking for. So I went to VScode and opened up the component for that page. Going through the imports I found something interesting.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc2xxodq70ogoppkhql04.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc2xxodq70ogoppkhql04.png" alt="VScode svg imports" width="800" height="588"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The SVGs were large (not good), but that wasn’t what got to me. They were imported as &lt;code&gt;ReactComponent&lt;/code&gt;. This meant the image would actually be rendered as svg elements. And being that size the elements would be massive. &lt;/p&gt;

&lt;p&gt;Aha!! I found the culprit!!&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 4: Test the hypothesis
&lt;/h3&gt;

&lt;p&gt;I then switched out the imports and changed the way the images were rendered from using the &lt;code&gt;svg&lt;/code&gt; tag to the &lt;code&gt;img&lt;/code&gt; tag.&lt;/p&gt;

&lt;p&gt;That's from the old import,&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbfq11tverlhngtxawmph.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbfq11tverlhngtxawmph.png" alt="SVG imported as React component" width="800" height="53"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And the old usage,&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvqspg8401x559be3ari3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvqspg8401x559be3ari3.png" alt="SVG used as React component" width="558" height="58"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Which is then rendered as,&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F95xijpmsp1esvi5s6v6d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F95xijpmsp1esvi5s6v6d.png" alt="Svg tag" width="800" height="121"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To the new import,&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffuli2ck1ptia5cq7bbnj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffuli2ck1ptia5cq7bbnj.png" alt="New SVG import" width="800" height="39"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And the new usage,&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fihsrr33riy464lq99ynh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fihsrr33riy464lq99ynh.png" alt="New SVG usage" width="800" height="54"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Which is then rendered as,&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn3wtw0wb01s13l5824k1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn3wtw0wb01s13l5824k1.png" alt="Img tag" width="766" height="34"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A simple change but this ensured the &lt;code&gt;svg&lt;/code&gt; tag stayed out of the picture.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I could also have requested for smaller SVGs too.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  Step 5: Take action
&lt;/h3&gt;

&lt;p&gt;I made the PR and after some explanation it got merged into beta. I went back to the command line,&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F91vnwc2lhklwnib4320b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F91vnwc2lhklwnib4320b.png" alt="Command line test 2" width="800" height="202"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hurray!!! 479kB!!! 🎉&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 6: Test and observe
&lt;/h3&gt;

&lt;p&gt;Went back to the Twitter card validator and confirmed that the preview image showed up. It did!!&lt;/p&gt;
&lt;h3&gt;
  
  
  Tests
&lt;/h3&gt;

&lt;p&gt;Different types of tests include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Unit:&lt;/strong&gt; Verify that individual, isolated parts work as expected.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Integration:&lt;/strong&gt; Verify that several units work together in harmony.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;End-to-End(e2e):&lt;/strong&gt; A helper robot that behaves like a user to click around the app and verify that it functions correctly. Sometimes called "functional testing" or e2e.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We're to write tests that give confidence in our software, and this presents a challenge with testing.&lt;/p&gt;

&lt;p&gt;In reference to this, &lt;a href="https://twitter.com/kentcdodds" rel="noopener noreferrer"&gt;Kent C Dodds&lt;/a&gt; expatiates on a tweet on writing tests by &lt;a href="https://twitter.com/rauchg" rel="noopener noreferrer"&gt;Guillermo Rauch&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-807626710350839808-968" src="https://platform.twitter.com/embed/Tweet.html?id=807626710350839808"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-807626710350839808-968');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=807626710350839808&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;You can read about that &lt;a href="https://kentcdodds.com/blog/write-tests" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Developments in Debugging
&lt;/h2&gt;

&lt;p&gt;No one likes frustration. As a result there have been advancements in debugging tools to improve the developer experience as touching tracking and fixing bugs/errors.&lt;/p&gt;

&lt;p&gt;No one wants to be this guy.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw6jtk6jswsln689385yh.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw6jtk6jswsln689385yh.jpeg" alt="Bug from missing period" width="474" height="348"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As such tooling has been evolved to reduce the surface area for bugs to reside. Some of these developments include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Better IDE support for debugging&lt;/li&gt;
&lt;li&gt;Static analysis &lt;/li&gt;
&lt;li&gt;Logging&lt;/li&gt;
&lt;li&gt;Open telemetry&lt;/li&gt;
&lt;li&gt;Command-line tools&lt;/li&gt;
&lt;li&gt;Profilers&lt;/li&gt;
&lt;li&gt;CI&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Communities
&lt;/h2&gt;

&lt;p&gt;In all honesty, I have found communities to be the most helpful resource when debugging. It's pacifying to know that someone else &lt;del&gt;shares your pain&lt;/del&gt; has encountered a similar problem. It's even better to know that one or more solutions have been implemented.&lt;/p&gt;

&lt;p&gt;The feeling of copy-pasting an error message and seeing several matching results from Stack Overflow is just soothing.&lt;/p&gt;

&lt;p&gt;Software engineering as a whole has benefited greatly from the sharing of knowledge. Thereby, removing the need to reinvent the wheel.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Most developers would confess that it's a fool's errand to hope to write bug-free code. Rather, it's more practical to write resilient software that can be debugged more easily.&lt;/p&gt;

&lt;p&gt;Similarly, good system designs bake in fault tolerance from the get-go. In reality, it's not &lt;strong&gt;if&lt;/strong&gt; they will occur rather &lt;strong&gt;when&lt;/strong&gt; will they occur. The most experienced engineers also have their demons.&lt;/p&gt;

&lt;p&gt;It takes time and practice. You have to get better at reading error messages and &lt;em&gt;Googling&lt;/em&gt;. But over time it gets easier and is a necessary skill to grow. Don’t allow early frustrations to keep you from trying. You’d struggle more at the beginning, don’t worry everyone does.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Everyone eventually cooks beans, but can you debug it effectively? That’s what will matter. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Hope this article helps.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://m-cacm.acm.org/magazines/2018/11/232215-modern-debugging/fulltext" rel="noopener noreferrer"&gt;https://m-cacm.acm.org/magazines/2018/11/232215-modern-debugging/fulltext&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.geeksforgeeks.org/software-engineering-debugging-approaches/" rel="noopener noreferrer"&gt;https://www.geeksforgeeks.org/software-engineering-debugging-approaches/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://kentcdodds.com/blog/write-tests" rel="noopener noreferrer"&gt;https://kentcdodds.com/blog/write-tests&lt;/a&gt;
&lt;a href="https://kentcdodds.com/blog/static-vs-unit-vs-integration-vs-e2e-tests" rel="noopener noreferrer"&gt;https://kentcdodds.com/blog/static-vs-unit-vs-integration-vs-e2e-tests&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://isocroft.medium.com/get-better-at-troubleshooting-and-debugging-software-11d0edd4dac5" rel="noopener noreferrer"&gt;https://isocroft.medium.com/get-better-at-troubleshooting-and-debugging-software-11d0edd4dac5&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/mindorks/bug-smashing-a-guide-to-debug-your-app-11278d832e13" rel="noopener noreferrer"&gt;https://medium.com/mindorks/bug-smashing-a-guide-to-debug-your-app-11278d832e13&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.isquaredsoftware.com/2019/01/blogged-answers-debugging-tips/" rel="noopener noreferrer"&gt;https://blog.isquaredsoftware.com/2019/01/blogged-answers-debugging-tips/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://flaviocopes.com/debugging/" rel="noopener noreferrer"&gt;https://flaviocopes.com/debugging/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.jotform.com/blog/bug-report/" rel="noopener noreferrer"&gt;https://www.jotform.com/blog/bug-report/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://siderlabs.com/blog/11-types-of-software-bugs/" rel="noopener noreferrer"&gt;https://siderlabs.com/blog/11-types-of-software-bugs/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.freecodecamp.org/news/what-is-a-software-post-mortem/" rel="noopener noreferrer"&gt;https://www.freecodecamp.org/news/what-is-a-software-post-mortem/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.katalon.com/resources-center/blog/regression-testing/" rel="noopener noreferrer"&gt;https://www.katalon.com/resources-center/blog/regression-testing/&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
      <category>debugging</category>
    </item>
    <item>
      <title>Why I decided to write</title>
      <dc:creator>Folafunmi</dc:creator>
      <pubDate>Sat, 05 Feb 2022 13:17:04 +0000</pubDate>
      <link>https://forem.com/playfulprogramming/why-i-decided-to-write-2l6k</link>
      <guid>https://forem.com/playfulprogramming/why-i-decided-to-write-2l6k</guid>
      <description>&lt;p&gt;I made this decision in the wake of serious thought, having considered various opinions I found on the web &lt;a href="https://stackoverflow.blog/2021/08/09/how-writing-can-advance-your-career-as-a-developer/" rel="noopener noreferrer"&gt;here&lt;/a&gt; and &lt;a href="https://www.swyx.io/three-strikes/" rel="noopener noreferrer"&gt;here&lt;/a&gt;, as well as my personal and professional growth.&lt;/p&gt;

&lt;p&gt;I've always admired writers. Their ability to construct a narrative, to limn a world entirely from static words, to communicate ideas, and to transfer knowledge amazed me. I've read genres from across the board, seems what's keenly considered as legendary and also sadly as mediocre.&lt;/p&gt;

&lt;p&gt;I've made up my mind, what isle I would like to belong to; what quality of content I want to publish. Consequently, I can boldly make the statement that,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For every word I write, I have read ten thousand more.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To stand on the shoulders of giants, my thoughts and opinions have been shaped from years of reading opinionated as well as technical articles, cuddling jargon, and hunting down every keyword that caught my eye.&lt;/p&gt;

&lt;p&gt;I never considered myself to be a writer but circumstance and undeniable advantages admit me into the class. Albeit with raw opinions, unrefined skills, and imposter syndrome which lay not far behind.&lt;/p&gt;

&lt;h2&gt;
  
  
  Writing is an art
&lt;/h2&gt;

&lt;p&gt;Writing, right from the dawn of time, has been used as a medium of communication. A means to share thoughts, feelings, and ideas. To express emotions and opinions through inert words, yet springing forth living ideas.&lt;/p&gt;

&lt;p&gt;Historically, entire civilizations, epics, and tales have been preserved by the estate of writing. The medium upon which these writings were done changed over time but the art persisted through the times emerging in various fields and cementing its place in history as an important medium of communication.&lt;/p&gt;

&lt;p&gt;The software engineering field seems to have taken a clue from this too. RFCs are write-ups that explain a concept concisely and have led to very important parts of the modern world lending credence to technologies like TCP, HTTP, etc.&lt;/p&gt;

&lt;p&gt;Blogging platforms like Medium, Dev.to, Hashnode emerged to aid engineers and those alike to have a means to rhyme to reason and put pen to paper. If you have an idea, it can easily be written down, publicized, vetted, and appraised by others.&lt;/p&gt;

&lt;p&gt;In helpful communities, a critical feature is feedback. As stated by great writers alike, feedback exists as a key factor in writing, upon which that which is brilliant is regarded as so, and that which is mediocre is done the mercy of being corrected. &lt;/p&gt;

&lt;p&gt;Of course, the keyword here is "helpful". The alternative atmosphere would lead to a hunting ground for smart alecks, an avenue for writers to be insulted, and worse of all for ideas, new or recycled, to be aborted right at its conception.&lt;/p&gt;

&lt;p&gt;Yet, choosing to step out of the shadows, brave the storm and become vulnerable, I choose to put my thoughts on a page. As a sign of growth and a snipe to the fear of the unknown. &lt;/p&gt;

&lt;p&gt;Plus, let's face it, haters will hate. Therefore, I adopt the Latin saying:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Illegitimi non carborundum!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Which when translated to English is,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Don't let the bastards get you down!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Reasons to write 🧐
&lt;/h2&gt;

&lt;p&gt;Ordinarily, there exist several reasons to write. From a means of communication to the documentation of an action, topic, or contract. All stand as valid but my decision to write stands a mere subset of the extent of reasons given.&lt;/p&gt;

&lt;p&gt;In making the decision to write, I considered several factors which swayed my decision to the eventual affirmative. Some of which I highlight in detail below:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. To gain mastery 💪🏾
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;"Excellence is an art won by training and habituation. We do not act rightly because we have virtue or excellence, but we rather have those because we have acted rightly. We are what we repeatedly do. Excellence, then, is not an act but a habit." - Aristotle&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I genuinely want to be a master communicator, to hone the skill of the explainer and be able to construct words that best describe my thought process on any subject.&lt;/p&gt;

&lt;p&gt;Initially, I'd been worried about giving the perfect analogy for a given scenario and had not been concerned with how such an analogy would be conceived. I was focused on the end goal and not on the journey. To give an analogy, I was only keen on reaching the peak of the mountain, not considering the climb.&lt;/p&gt;

&lt;p&gt;In the book, Mastery: The Keys to Success and Long-Term Fulfillment, George Leonard writes,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Perhaps we'll never know how far the path can go, how much a human being can truly achieve until we realize that the ultimate reward is not a gold medal but the path itself.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I'd been self-critical, comparing myself to the best of the best, masters in their craft, forgetting that all I needed to be was just that bit better than I was yesterday and wait for the compounding effect to run its course.&lt;/p&gt;

&lt;p&gt;Where for a million zeros it remains zero, but a million tiny steps (in the right direction) can take you quite far.&lt;/p&gt;

&lt;p&gt;Right now, I've decided to stay on the path of mastery and become a master by the process. To learn the rules and not just the exceptions. To put out an idea however raw it may be.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. To better communicate ideas 📣
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Great ideas deserve to be shared.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In my stint in software engineering, with the majority of my experience tilted to the front end of the web, I've come across many libraries and frameworks with newer ones surfacing every other week.&lt;/p&gt;

&lt;p&gt;I've heard and read ideas that I agreed with and others I didn't. Writing would help me better communicate my understanding of such ideas to my teammates.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Software Engineering is teamwork and an effective team is one that can share ideas openly and collaborate.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the past, there were scenarios I'd tried to explain a concept to a teammate with hopes it'd get adopted, only to be met with awkward silence.&lt;/p&gt;

&lt;p&gt;Similarly, I'd tried to explain an architectural change that I considered beneficial only to be met with the doubtful intro, &lt;strong&gt;"So you're saying..."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In line with this, I recently encountered an &lt;a href="https://www.swyx.io/three-strikes" rel="noopener noreferrer"&gt;article&lt;/a&gt; by Shawn "Swyx" Wang on when to consider blogging about an idea, which he called the three-strikes rule. The third time the charm.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The 3rd time we reference an idea in a conversation, we have to blog about it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://twitter.com/swyx" rel="noopener noreferrer"&gt;Swyx&lt;/a&gt; further explains,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;By the third time you refer to an idea, it’s no longer a coincidence. It’s a pattern. You’re increasingly likely to refer to it again in the future. It’s marinated in your head for a bit, and you’ve likely gained some experience explaining it to others. It’s also not so old that it may have lost relevance.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Writings also show that you know your stuff. Signal to employers that you're a good written communicator and upfront presents your views about certain technologies. &lt;/p&gt;

&lt;p&gt;In my experience and research, even having opposing opinions on a particular technology will not deter would-be employers as a good argument would prove diligence to detail.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Exposure to opportunities 🎉
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;It's undeniable; good writing deserves some accolades.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Asides from the obvious clout that comes with putting out quality pieces, writing puts your knowledge out in front of recruiters and possible employers.&lt;/p&gt;

&lt;p&gt;Essentially, by writing, I want to &lt;a href="https://www.swyx.io/create-luck/" rel="noopener noreferrer"&gt;create my own luck&lt;/a&gt;. Be it in jobs, speaking engagements, or community clout.&lt;/p&gt;

&lt;p&gt;For example, consider the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Upon creating a newsletter and being exposed, this &lt;a href="https://twitter.com/sebastienlorber/status/1231981307590213633" rel="noopener noreferrer"&gt;tweet&lt;/a&gt; led &lt;a href="https://twitter.com/sebastienlorber?lang=en" rel="noopener noreferrer"&gt;Sebastien Lorber&lt;/a&gt; to get hired to work on &lt;a href="https://docusaurus.io/" rel="noopener noreferrer"&gt;Docusaurus&lt;/a&gt; at Meta(Facebook)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://twitter.com/Linus_Borg" rel="noopener noreferrer"&gt;Thorsten Lünborg&lt;/a&gt; joined the &lt;a href="https://github.com/vuejs" rel="noopener noreferrer"&gt;Vue&lt;/a&gt; core team because of his work on responding on their community forum, without writing contributing to the codebase.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Just to name a few.&lt;/p&gt;

&lt;p&gt;I've found that recruiters and employers want to reach out. Everyone wants the best and brightest working for them. &lt;a href="https://andela.com/insights/indeed-survey-83-hiring-managers-say-tech-talent-shortage-hurts-business/" rel="noopener noreferrer"&gt;This study&lt;/a&gt; tells of tech talent shortage. &lt;/p&gt;

&lt;p&gt;This shows that opportunities abound, but if I never put myself out there I won't see any of them.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Knowledge reinforcement 🧠
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;A good teacher is firstly a good student.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To properly communicate a concept takes understanding the concept to relatively fine details. For example, writing a beginner's tutorial means you have to explain key concepts without reliance on jargon that might abstract away sections in which your understanding is lacking.&lt;/p&gt;

&lt;p&gt;In an interview I did, I was asked what a bundler was. I knew of Webpack, Rollup, Parcel, Snowpack, and Vite. Yet I couldn't give a simple definition for what a bundler was without repeating the word "bundle"😅.&lt;/p&gt;

&lt;p&gt;Writing forces you to fill in gaps in your understanding, nudging you towards better understanding of the concept. The more you understand, the easier it is for you to communicate simply without having to respond to all questions with "it depends"😜.&lt;/p&gt;

&lt;p&gt;Feedback from the community also presents another learning route. Good explanations will be praised and bad explanations will be &lt;del&gt;shredded&lt;/del&gt; corrected. All in all, it serves as a learning experience.&lt;/p&gt;

&lt;p&gt;As &lt;a href="https://twitter.com/swyx" rel="noopener noreferrer"&gt;Swyx&lt;/a&gt; shares while on &lt;a href="https://kentcdodds.com/chats/01/12/you-can-learn-a-lot-for-the-low-price-of-your-ego-with-shawn-wang" rel="noopener noreferrer"&gt;a podcast&lt;/a&gt; with &lt;a href="https://twitter.com/kentcdodds" rel="noopener noreferrer"&gt;Kent C. Dodds&lt;/a&gt;,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You can learn so much on the internet for the low, low price of your ego. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  5. Monetary benefits 🤑
&lt;/h3&gt;

&lt;p&gt;Writing aids the knowledge of the writer, but it also provides knowledge for its reader. Therefore, it qualifies as a service that can be rendered and as such can be monetized.&lt;/p&gt;

&lt;p&gt;Several platforms exist that pay developers for composing articles and or tutorials. A list of such writer programs can be found at &lt;a href="https://github.com/malgamves/CommunityWriterPrograms" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It's exciting to be paid for sharing in knowledge, and this incentive makes developers(myself included) inclined to learn more and in turn write better software.&lt;/p&gt;

&lt;p&gt;This provides nice benefits as the community at large is uplifted. It spurs better articles to be written just as awards such as the Emmys and Oscars spurred better movies being made.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Preserve a snapshot of my growth 📈
&lt;/h3&gt;

&lt;p&gt;Recently, I had to explain a concept to a new developer, it didn't go well. I noticed that I used much more technical jargon than if I'd been asked a few years ago.&lt;/p&gt;

&lt;p&gt;I'd forgotten how I learned the concept as such my delivery was less effective. I had become more advanced and as such had left behind heuristics and simple illustrations that'd helped me understand. This is sometimes referred to as the &lt;a href="https://developers.google.com/tech-writing/one/audience#curse_of_knowledge" rel="noopener noreferrer"&gt;curse of knowledge&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I want to change this. My writing would be a preserved state of my knowledge per time and would serve to help myself as well as other developers at that stage in their growth and career.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Monitor my growth 👀
&lt;/h3&gt;

&lt;p&gt;Writing will provide insight into how my understanding evolves. How references and examples changed with time. My personal source of observability.&lt;/p&gt;

&lt;p&gt;This would inform of key metrics like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Showing topics for which my understanding is subpar or lacking, &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Providing an avenue to see how best to structure explanations&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Knowing what ideas seem to gain traction?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All provided alongside input from the community.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion 🏁
&lt;/h2&gt;

&lt;p&gt;In hindsight, I wish I'd taken this decision sooner. The benefits far outweigh the risks of not being good enough.&lt;/p&gt;

&lt;p&gt;However, late definitely beats never. And to those who are or ever hope to be writers, my advice is, &lt;strong&gt;Just write!&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://stackoverflow.blog/2021/08/09/how-writing-can-advance-your-career-as-a-developer/" rel="noopener noreferrer"&gt;https://stackoverflow.blog/2021/08/09/how-writing-can-advance-your-career-as-a-developer/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stackoverflow.blog/2021/08/20/the-overflow-87-advance-your-developer-career-by-writing/" rel="noopener noreferrer"&gt;https://stackoverflow.blog/2021/08/20/the-overflow-87-advance-your-developer-career-by-writing/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.swyx.io/create-luck/" rel="noopener noreferrer"&gt;https://www.swyx.io/create-luck/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.swyx.io/three-strikes/" rel="noopener noreferrer"&gt;https://www.swyx.io/three-strikes/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://andela.com/insights/indeed-survey-83-hiring-managers-say-tech-talent-shortage-hurts-business/" rel="noopener noreferrer"&gt;https://andela.com/insights/indeed-survey-83-hiring-managers-say-tech-talent-shortage-hurts-business/&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>writing</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
