<?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>DEV Community: Sakib Miyahn</title>
    <description>The latest articles on DEV Community by Sakib Miyahn (@sakibmiyahn).</description>
    <link>https://dev.to/sakibmiyahn</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%2F3419283%2F8ffa6387-49a8-4032-902d-afeb98363f56.png</url>
      <title>DEV Community: Sakib Miyahn</title>
      <link>https://dev.to/sakibmiyahn</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sakibmiyahn"/>
    <language>en</language>
    <item>
      <title>Setting up Prettier, ESLint, Airbnb, Stylelint, Husky, and lint-staged for a consistent Node.js workflow</title>
      <dc:creator>Sakib Miyahn</dc:creator>
      <pubDate>Thu, 07 Aug 2025 11:35:21 +0000</pubDate>
      <link>https://dev.to/sakibmiyahn/setting-up-prettier-eslint-airbnb-stylelint-husky-and-lint-staged-for-a-consistent-nodejs-20n6</link>
      <guid>https://dev.to/sakibmiyahn/setting-up-prettier-eslint-airbnb-stylelint-husky-and-lint-staged-for-a-consistent-nodejs-20n6</guid>
      <description>&lt;p&gt;Whether you’re coding solo or working in a team, one thing becomes obvious fast: style inconsistencies and formatting nitpicks waste time.&lt;/p&gt;

&lt;p&gt;Over the years, I’ve landed on a setup that saves mental overhead, keeps the codebase clean, and scales well across teams and projects. In this guide, I’ll walk you through how I configure Prettier, ESLint with Airbnb’s style guide, Stylelint, Husky, and lint-staged in a Node.js environment.&lt;/p&gt;

&lt;p&gt;Let’s start with a high-level view of what each tool brings to the table.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;📦 Overview: What Each Tool Does (and Why You Need It)&lt;/strong&gt;
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Tool&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;What It Solves&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://prettier.io/docs/" rel="noopener noreferrer"&gt;&lt;strong&gt;Prettier&lt;/strong&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Automatically formats code to a consistent style across file types.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://eslint.org/docs/latest/" rel="noopener noreferrer"&gt;&lt;strong&gt;ESLint&lt;/strong&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Detects syntax errors and enforces coding best practices in JS/TS code.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/airbnb/javascript" rel="noopener noreferrer"&gt;&lt;strong&gt;Airbnb Config&lt;/strong&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;A widely adopted ESLint config that enforces readable, consistent JS code.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://stylelint.io/" rel="noopener noreferrer"&gt;&lt;strong&gt;Stylelint&lt;/strong&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Linter for CSS/SCSS that catches errors and enforces style conventions.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/lint-staged/lint-staged#readme" rel="noopener noreferrer"&gt;&lt;strong&gt;lint-staged&lt;/strong&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Ensures linters only run on staged files — fast and targeted.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://typicode.github.io/husky/" rel="noopener noreferrer"&gt;&lt;strong&gt;Husky&lt;/strong&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Hooks into Git to run checks before code is committed, keeping your main branch clean.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;When combined, these tools reduce the surface area for bugs, reduce friction in code reviews, and let you focus on solving real problems — not arguing about trailing commas.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;🧹 Step 1: Prettier — Your Formatting Backbone&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Prettier is an opinionated formatter. It doesn’t care how you want your code to look — it enforces a consistent, readable style. It supports many file types: .html, .json, .js, .ts, .css, .scss, .md, etc.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;🔧 Install&lt;/strong&gt;
&lt;/h3&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; &lt;span class="nt"&gt;--save-dev&lt;/span&gt; prettier
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a &lt;code&gt;.prettierrc&lt;/code&gt; file at the root of your project. You can modify these settings as per your preferences. Refer to the &lt;a href="https://prettier.io/docs/" rel="noopener noreferrer"&gt;Prettier&lt;/a&gt; documentation for all available options. Here's a sample configuration I use:&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;"bracketSpacing"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"printWidth"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"singleQuote"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"tabWidth"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"trailingComma"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"all"&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;&lt;strong&gt;Why these settings?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;bracketSpacing&lt;/code&gt; - Improves readability with space inside object literals: &lt;code&gt;{ key: value }&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;printWidth&lt;/code&gt; - I find 80 too cramped; 120 gives more breathing room, especially for modern monitors.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;singleQuote&lt;/code&gt; - JavaScript traditionally uses single quotes; this reduces diff noise and aligns with many style guides.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;tabWidth&lt;/code&gt; - Standard size, especially in JS/TS communities.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;trailingComma&lt;/code&gt; - Makes diffs cleaner and reduces bugs when adding new lines.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Create a &lt;code&gt;.prettierignore&lt;/code&gt; file at the root of your project to exclude files/directories you don’t want Prettier to touch — generated files, IDE configs, etc.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;node_modules
build
dist
coverage
.vscode
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;🧠 Step 2: ESLint + Airbnb — Code Quality &amp;amp; Best Practices&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Where Prettier handles style, ESLint enforces logic and structure. It catches things like unused variables, accidental globals and subtle syntax issues.&lt;/p&gt;

&lt;p&gt;The Airbnb style guide is battle-tested and opinionated. It promotes clarity, consistency and best practices out of the box.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;🔧 Install dependencies&lt;/strong&gt;
&lt;/h3&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; &lt;span class="nt"&gt;--save-dev&lt;/span&gt; eslint eslint-plugin-node eslint-config-node
npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save&lt;/span&gt; &lt;span class="nt"&gt;-dev&lt;/span&gt; eslint-plugin-prettier eslint-config-prettier
npx install-peerdeps &lt;span class="nt"&gt;--dev&lt;/span&gt; eslint-config-airbnb-base
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Note: Use &lt;code&gt;eslint-config-airbnb&lt;/code&gt; instead of &lt;code&gt;airbnb-base&lt;/code&gt; if you’re working with React.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Create an &lt;code&gt;.eslintrc.json&lt;/code&gt; file at the root of your project. Here's a sample configuration that uses the Airbnb base rules (which exclude React-specific rules). It also adds Prettier and node config as a rule. Check out &lt;a href="https://eslint.org/docs/latest/" rel="noopener noreferrer"&gt;ESLint&lt;/a&gt; docs for full sets of available rules:&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;"env"&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;"browser"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"commonjs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"es2021"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&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;"extends"&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;"airbnb-base"&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"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"plugin:node/recommended"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"plugins"&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;"prettier"&lt;/span&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;"prettier/prettier"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"warn"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"no-console"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"warn"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"no-unused-vars"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"warn"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"no-shadow"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"off"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"no-underscore-dangle"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"off"&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;&lt;strong&gt;Key rules explained:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;prettier/prettier&lt;/code&gt; - ESLint surfaces Prettier issues, but only as warnings.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;no-console&lt;/code&gt; - Logs are useful during development, but shouldn’t ship to prod.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;no-unused-vars&lt;/code&gt; - Helps avoid bloated, misleading code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;no-underscore-dangle&lt;/code&gt; - I often use _id from MongoDB, so this rule gets turned off.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;🎨 Step 3: Stylelint — Keep Your Stylesheets Clean&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Stylelint works just like ESLint, but for styles. It ensures your SCSS/CSS is consistent, avoids deprecated syntax and promotes clean layout logic.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;🔧 Install&lt;/strong&gt;
&lt;/h3&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; &lt;span class="nt"&gt;--save-dev&lt;/span&gt; sass stylelint stylelint-config-standard-scss stylelint-config-prettier
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create &lt;code&gt;.stylelintrc.json&lt;/code&gt; in the project root. Here's a sample configuration:&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="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"stylelint-config-standard-scss"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"stylelint-config-prettier"&lt;/span&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;"color-function-notation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"legacy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"selector-class-pattern"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&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;&lt;strong&gt;What this does:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;standard-scss&lt;/code&gt; gives us a solid base config for SCSS.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;tylelint-config-prettier&lt;/code&gt; disables rules that conflict with Prettier.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We relax strict class naming rules &lt;code&gt;selector-class-pattern&lt;/code&gt; to suit different naming conventions (BEM, utility-first, etc.).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;⚡ Step 4: lint-staged — Lint Only What Changed&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Without lint-staged, Husky would run ESLint/Prettier on the whole codebase for every commit. That’s slow and unnecessary. lint-staged is a package that can be used to run formatting and linting commands on staged files in a Git repo.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;🔧 Install&lt;/strong&gt;
&lt;/h3&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; &lt;span class="nt"&gt;--save-dev&lt;/span&gt; lint-staged
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;lint-staged will run specific commands on staged files before committing them. Add the following configuration to your &lt;code&gt;package.json&lt;/code&gt;. The below configures lint-staged to run Prettier, Stylelint and ESLint. Only add the Stylelint script for front-end projects:&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;"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,ts,jsx,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="s2"&gt;"prettier --write"&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"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"*.{css,scss,json,md}"&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;"prettier --write"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"stylelint --allow-empty-input"&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;blockquote&gt;
&lt;p&gt;This setup makes sure only staged files are linted/formatted, keeping pre-commit hooks fast and focused.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;🔐 Step 5: Husky — Git Gatekeeper&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://typicode.github.io/husky/" rel="noopener noreferrer"&gt;Husky&lt;/a&gt; allows us to run scripts at key Git lifecycle moments. Here, we’ll use it to run lint-staged before any commit. Thus code only ever gets into the repo after it has been consistently formatted and verified to be free of linting errors. This is a particularly big advantage in a team setting.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;🔧 Install and set up&lt;/strong&gt;
&lt;/h3&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; &lt;span class="nt"&gt;--save-dev&lt;/span&gt; husky
npx husky init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;init&lt;/code&gt; command simplifies setting up Husky in a project. It creates a &lt;code&gt;pre-commit&lt;/code&gt; script in &lt;code&gt;.husky/&lt;/code&gt; and updates the &lt;code&gt;prepare&lt;/code&gt; script in &lt;code&gt;package.json&lt;/code&gt;. Modifications can be made later to suit your workflow.&lt;/p&gt;

&lt;p&gt;Update the &lt;code&gt;.husky/pre-commit&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx lint-staged
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;This ensures your staged files pass all checks before being committed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Create &lt;code&gt;.husky/install.mjs&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Skip Husky install in production and CI&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NODE_ENV&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;production&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;CI&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;true&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;husky&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;husky&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;husky&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;This ensures husky is only installed in dev environment.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  🛠️ Step 6: Helpful NPM Scripts
&lt;/h2&gt;

&lt;p&gt;Add these to your &lt;code&gt;package.json&lt;/code&gt; for manual use or CI pipelines, adjust according to your project setup:&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"lint"&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 './**/*.@(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="nl"&gt;"lint:fix"&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 './**/*.@(js|jsx|ts|tsx)' --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;"prettier:check"&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 --check './**/*.{js,ts,json,md,css,scss}'"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"prettier:write"&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 './**/*.{js,ts,json,md,css,scss}'"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"style:check"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"stylelint '**/*.{css,scss}' --allow-empty-input"&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;"node .husky/install.mjs"&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;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;lint&lt;/code&gt; - This script will run ESLint on all JavaScript, TypeScript, JSX and TSX files in your project.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;lint:fix&lt;/code&gt; - This will do the same as the lint script but will also attempt to automatically fix any issues that ESLint can handle.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;prettier:write&lt;/code&gt; - This script will format all JS, JSX, TS, TSX, JSON, CSS, SCSS and Markdown files using Prettier. This ensures consistency in both code and documentation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;prettier:check&lt;/code&gt; - This will check if all the specified files adhere to the formatting rules specified by Prettier. This is especially useful as a pre-commit or CI/CD step to ensure that no non-formatted files get committed or deployed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;style:check&lt;/code&gt; - This will check if all the specified CSS, SCSS files adhere to the formatting rules specified by Stylelint. Only add for front-end projects.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;prepare&lt;/code&gt; - This will only run Husky in a non-production environment.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can adjust the patterns like &lt;code&gt;./**/*.@(js|jsx|ts|tsx|json|css|scss|md)&lt;/code&gt; to fit the specific needs of your project, and which directories or file types you want to include/exclude.&lt;/p&gt;

&lt;h3&gt;
  
  
  ⚙️ Using in your Workflow
&lt;/h3&gt;

&lt;p&gt;Whenever you're about to commit, you can run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git add &lt;span class="nb"&gt;.&lt;/span&gt;
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Set up linting and formatting"&lt;/span&gt;
&lt;span class="c"&gt;# lint-staged script will run every time you commit&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;This will ensure that your code is both linted and formatted. If anything had not been set up correctly, you would likely get errors during commit.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  🧩 Bonus: VS Code Setup for Auto-Formatting
&lt;/h2&gt;

&lt;p&gt;To make all of this seamless, configure VS Code to format on save and use the following extensions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint" rel="noopener noreferrer"&gt;ESLint&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=stylelint.vscode-stylelint" rel="noopener noreferrer"&gt;Stylelint&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode" rel="noopener noreferrer"&gt;Prettier - Code formatter&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Put the following in &lt;code&gt;.vscode/settings.json&lt;/code&gt; in the project (you can also put these settings in your User Preferences file):&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;"[javascript]"&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;"editor.defaultFormatter"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"esbenp.prettier-vscode"&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;"typescript.tsdk"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node_modules/typescript/lib"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"[typescript]"&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;"editor.defaultFormatter"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"esbenp.prettier-vscode"&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;"[javascriptreact]"&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;"editor.defaultFormatter"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"esbenp.prettier-vscode"&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;"[typescriptreact]"&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;"editor.defaultFormatter"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"esbenp.prettier-vscode"&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;"[scss]"&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;"editor.defaultFormatter"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"esbenp.prettier-vscode"&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;"scss.lint.emptyRules"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ignore"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"stylelint.validate"&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;"css"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"scss"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"editor.formatOnSave"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&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;blockquote&gt;
&lt;p&gt;The above set up, will allow the extensions to lint and format on Save.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  ✅ Final Thoughts
&lt;/h2&gt;

&lt;p&gt;This setup may feel like a lot up front, but once it’s in place, it quietly handles all the repetitive formatting, catches subtle issues and keeps your Git history clean.&lt;/p&gt;

&lt;p&gt;It’s not about obsessing over code style. It’s about freeing up mental bandwidth so you can focus on solving real problems, not arguing over trailing commas or indentation.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;🤔 What Do You Use?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;I’d love to hear how others approach this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;What’s your go-to setup?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Any must-disable rules in your projects?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Do you skip this entirely for small experiments?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let me know your take. Always curious to hear how other devs keep their code clean.&lt;/p&gt;

&lt;p&gt;🛠️ Written by &lt;a href="https://sakibmiyahn.com" rel="noopener noreferrer"&gt;Sakib Miyahn&lt;/a&gt; - Full-Stack Software Engineer - Sydney, AU.&lt;/p&gt;

</description>
      <category>node</category>
      <category>eslint</category>
      <category>prettier</category>
      <category>husky</category>
    </item>
  </channel>
</rss>
