This episode covers automating code quality: installing and configuring ESLint to catch pattern errors, using Prettier for consistent formatting, and uniting both through npm scripts. You build professional-team code standards.

Working code is the baseline; code that is readable and consistent is the professional standard. As a project grows or is worked on by many people, small problems turn into big ones: differing writing styles, rules violated without noticing, and bugs that should have been prevented automatically. This is where tooling comes in.
Episode 20 covers the two tools that form the backbone of modern JavaScript code quality: ESLint for catching errors and bad patterns, and Prettier for formatting code consistently. You'll also unite both through npm scripts so everything can be run with one command.
The most important lesson of this episode: machine-enforced consistency beats forgotten verbal agreements. You'll feel how calm it is to work when tools enforce standards rather than relying on memory.
Humans aren't consistent, and code reflects that. Without tools, everyone writes in their own style: different quotes, different indentation, unused variables, and loose comparisons that should be strict. Small bugs like these accumulate and get in the way.
Two categories of tools handle two different problems:
== that should be ===, unreachable code.They're different but complementary: the linter asks is the code correct?, the formatter asks is the code tidy?.
ESLint is installed as a development dependency — a tool needed during development, not when the application runs:
npm init -y
npm install --save-dev eslintnpm install --save-dev eslint puts ESLint in devDependencies. This category matters: build tools don't get bundled into the production application. After installation, run the interactive configuration initialization:
npx eslint --initnpx eslint --init guides you through choosing a configuration style. On modern versions, the result is an eslint.config.js file — the flat config format that has been the standard since ESLint 9. You can choose a rule set that fits a Node or browser project.
With the configuration ready, run linting on a file or directory:
npx eslint srcnpx eslint src checks all files in the src directory and shows the problems found. An example problem ESLint catches:
const nilai = "10";
if (nilai == 10) {
console.log("Perbandingan longgar");
}The if (nilai == 10) line uses loose comparison. With the eqeqeq rule active, ESLint warns because the team rule requires ===. ESLint reports the exact line, the violated rule, and a fix suggestion — sometimes it can fix it automatically with npx eslint src --fix.
Some of the highest-impact rules for JavaScript:
no-unused-vars: catches variables that are never used.eqeqeq: requires strict comparison.no-undef: catches uses of undeclared variables.no-unreachable: flags code after return.Every rule can be customized. The rules a team chooses are a collective decision, then enforced automatically — that's why linters work.
Prettier removes style debates with one automatic answer:
npm install --save-dev prettier
npx prettier --write srcnpm install --save-dev prettier installs the formatter, and npx prettier --write src formats every file in src directly. You don't choose preferences case by case — Prettier decides, and the result is always consistent. This is what makes all team members' code look like it was written by one person.
Prettier works with sensible defaults but can be configured through a .prettierrc file:
{
"semi": true,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "all"
}"singleQuote": true uses single quotes, "tabWidth": 2 sets indentation, and "trailingComma": "all" adds commas at the end of multiline lists. This consistency applies to the whole team, whatever the personal preferences.
ESLint and Prettier can clash — for instance, both control line style. The solution: disable style rules in ESLint that belong to Prettier's domain. In modern projects, this is automatic when using a built-in config like eslint-config-prettier:
npm install --save-dev eslint-config-prettiereslint-config-prettier turns off all ESLint rules that are unnecessary because Prettier already handles them. The result is a clean division of labor: ESLint handles correctness, Prettier handles tidiness.
Instead of typing npx eslint src and npx prettier --write src repeatedly, save both as npm scripts in package.json:
{
"name": "project-lint",
"type": "module",
"scripts": {
"lint": "eslint src",
"format": "prettier --write src",
"check": "npm run lint && npm run format"
}
}"lint": "eslint src" and "format": "prettier --write src" are commands callable via npm run lint and npm run format. The check script chains both. Using npm scripts means the exact same commands run on your laptop and in CI — no environment differences.
With scripts defined, the daily workflow becomes simple:
npm run lint
npm run formatnpm run lint and npm run format become the only commands you need to remember. In episode 21 you'll see how scripts like these are called automatically by build tools and CI.
Tip
Get into the habit of running npm run lint and npm run format before committing. In professional team projects, this step is usually enforced automatically by husky and lint-staged — but learning the manual habit first will make you understand why the automation exists.
Episode 20 automated your code standards: ESLint for catching errors and bad patterns, Prettier for consistent formatting, eslint-config-prettier for avoiding conflicts, and npm scripts for running everything with one command.
Key takeaways:
devDependencies.npx eslint src reports problems; npx eslint src --fix fixes automatically.npx prettier --write src formats all files at once.eslint-config-prettier prevents clashes between the two tools.In the next episode 21 we'll cover build tools, bundlers, and runtime environments — how bundlers like Vite and esbuild work, the differences between the Node.js, Deno, and Bun runtimes, and the practice of running modern projects with a build script. You'll see how all the module and tooling episodes connect.