15 — The Ecosystem: Formatting, Linting, and Build Tooling
"A bunch of config files to copy from the last project" was my ecosystem model, and it never explained what any file did. Writing it down separated the concerns: three tool categories each own one job — formatting (how code looks), linting (whether code follows rules), and building (how code compiles and bundles) — and around them sits a small set of type-adjacent libraries that extend what the compiler can do. [1] Once each tool's job was distinct in my head, configuring a project stopped being copy-paste.
The framing is that the type checker (tsc) is only one layer. It catches type errors. But a real project also needs its code to look consistent across a team, to follow agreed-upon rules beyond just types, and to compile and bundle efficiently for production. Each of those is a separate tool, and conflating them is where most of my tooling confusion came from.
Formatting: how code looks
A formatter automatically adjusts code style — spacing, indentation, line breaks, quotes — so that everyone's code looks the same [2]. Prettier is the dominant choice: it's opinionated, it parses the code and rewrites it in one canonical style, and it integrates with editors to format on save. The point isn't that Prettier's style is objectively best; it's that one style eliminates every "tabs vs. spaces" argument on a team. Once formatting is automated, code review stops surfacing nitpicks and focuses on substance.
A newer contender, Biome (formerly Rome), combines formatting and linting in one fast Rust-based tool [3]. It's an effort to replace the Prettier-plus-ESLint pair with a single, faster tool. For greenfield projects it's increasingly viable; for existing projects the Prettier + ESLint combo remains the established default.
Linting: whether code follows rules
A linter analyzes code for potential errors, suspicious patterns, and style/rules that a formatter doesn't catch [4]. ESLint is the standard: it's configurable with rules that enforce everything from "no unused variables" to "no implicit any" to project-specific conventions. Where Prettier handles how the code looks, ESLint handles what the code does — catching bugs and enforcing practices a formatter can't see.
The split worth internalizing: formatters and linters cover different ground, and running both is normal. A formatter never flags a logic smell; a linter never reformats your indentation (or shouldn't — ESLint's stylistic rules are increasingly handed off to formatters). The modern setup is Prettier for formatting plus ESLint (with @typescript-eslint) for TypeScript-aware rules, each owning its lane.
Build tools: compilation and bundling
Build tools handle turning source into something that runs — compiling TypeScript, bundling modules, and preparing assets for production [5]. The options the roadmap highlights sit on a spectrum of speed and configuration:
- webpack — the long-standing bundler. Powerful and mature, with a large plugin ecosystem, but configuration-heavy and slower for large projects.
- Vite — the modern default for many new projects. Uses native ES modules in development for instant startup, and Rollup for production builds. Fast dev server is its headline feature.
- esbuild — an extremely fast Go-based bundler/minifier, often used as a lower-level tool inside others [6].
- swc — a super-fast Rust-based compiler, used by frameworks (Next.js, etc.) to compile TypeScript/JSX at speed [7].
- Parcel — a zero-configuration build tool that aims to work out of the box with minimal setup.
The practical pattern: for new frontend projects, Vite is the common starting point; for libraries or Node projects, tsup (built on esbuild) or a direct tsc emit; for frameworks like Next.js, the build tool is chosen and configured by the framework. The unifying trend is speed — esbuild and swc, both written in systems languages, have replaced tsc itself for the emit step in many setups, while tsc is reserved for type-checking.
Type-adjacent libraries: extending the compiler
Beyond the build chain, a few libraries extend what TypeScript can express or check. The roadmap points at several, and two categories matter most to me:
Runtime validation that mirrors types. Zod is the standout — a schema-first validation library where I define a schema in Zod and derive a TypeScript type from it [8]. This closes the gap between compile-time types and runtime data: the same schema validates incoming JSON and provides the type for the rest of the code. For API boundaries, form inputs, and any data crossing a trust boundary, Zod means my runtime checks and my types can't drift apart.
Type-aware developer tools. ts-node (running TypeScript directly), ts-morph (programmatic AST manipulation for codemods), ts-jest (TypeScript support in Jest), and typesync (auto-installing @types/* packages) are utilities that make working in a TypeScript codebase smoother. Each addresses a specific workflow pain; none are mandatory, but they're worth knowing when the need arises.
How I use this
My defaults: Prettier (or Biome on greenfield) for formatting, format-on-save in the editor, no formatting debates in review; ESLint with @typescript-eslint for rules, keeping stylistic rules minimal and letting the formatter own appearance; and the project-appropriate build tool — Vite for new frontend work, tsup or tsc for libraries, whatever the framework picks for app frameworks. For data crossing trust boundaries (API responses, form input), I reach for Zod to validate at runtime and derive the type from the same schema, so the two can't drift. The discipline that pays off is keeping each tool in its lane — formatter for looks, linter for rules, compiler for types, build tool for output — and resisting the urge to make one tool do another's job, which is where configurations become tangled.
References
[1] The New Stack, "What Is TypeScript?," 2024. [Online]. Available: https://thenewstack.io/what-is-typescript/
[2] Prettier, "What is Prettier?," 2024. [Online]. Available: https://prettier.io/docs/en/why-prettier.html
[3] Biome, "Biome — Format and lint your code," 2024. [Online]. Available: https://biomejs.dev
[4] ESLint, "Introduction to ESLint," 2024. [Online]. Available: https://eslint.org/
[5] Vite, "Vite — Next Generation Frontend Tooling," 2024. [Online]. Available: https://vitejs.dev
[6] evanw, "esbuild — An extremely fast bundler and minifier," 2024. [Online]. Available: https://esbuild.github.io/
[7] swc, "swc — a super-fast TypeScript/JavaScript compiler written in Rust," 2024. [Online]. Available: https://swc.rs/
[8] Zod, "Zod — TypeScript-first schema validation," 2024. [Online]. Available: https://zod.dev/
Knowledge check · Question 1 of 5
A formatter like Prettier is responsible for…
Comments
Leave a Comment
You must be signed in to comment
0 Comments
No comments yet. Be the first to comment!