Most projects don't need a plugin ecosystem. They need a bundler, a linter, and ten minutes.

Keep the stack boring

The average side project ships with Webpack, Babel, PostCSS, a custom ESLint config, Prettier, Husky, lint-staged, and three Vite plugins the developer added "just in case." None of it gets removed. Half of it never runs.

Here's a setup that covers 90% of cases and takes about ten minutes to configure:

bash.ts
npm create vite@latest my-app -- --template react-ts
cd my-app && npm install

That's a TypeScript-aware React app with fast HMR, a production build that tree-shakes, and zero configuration debt. Add one ESLint pass:

bash.ts
npm install -D eslint @eslint/js

A flat eslint.config.js with the recommended ruleset catches real mistakes without fighting your team. That's your entire toolchain. Seriously.

The temptation to add more is real — a path alias here, a bundle-analyser plugin there. Resist it until you have a concrete problem. Bundle size hurting? Add rollup-plugin-visualizer then. Absolute imports annoying? Add resolve.alias to vite.config.ts then. Tools should arrive when they solve something, not when you imagine they might.

The same discipline applies to the back end. A Node script with native fetch, fs/promises, and TypeScript via ts-node or tsx handles most utility work. You don't need a framework for a five-route API.

Complexity compounds. Every added tool is a version to pin, a config to maintain, and a surface for breakage when Node upgrades. The builds that age well are the ones that started minimal and added deliberately — not the ones that imported an entire ecosystem on day one.

Start with bundlers in plain English if you're unsure what Vite is actually doing. Then ask yourself what problem you're solving before reaching for anything else.