SVG Optimization for Icons: Minify Markup and Embed as Data URLs
Shrink SVG icons for the web — strip comments and whitespace, choose inline vs data URLs, and know when you still need a full SVGO pipeline.
Vite vs webpack vs esbuild — a practical comparison of modern JavaScript build tools, when to use each, and what to pick for new projects in 2026.
By codefunc
Build tools transform your source code into production-ready bundles. The choice matters — it affects development speed, build times, and what optimizations are possible. In 2026, three tools dominate: Vite for developer experience, Webpack for flexibility, and esbuild for raw speed.
Bottom line: Use Vite for new projects — it has the best developer experience with instant HMR. Use Webpack when you need complex configurations or have an existing Webpack codebase. Use esbuild directly when you need maximum build speed and minimal configuration. Most teams should start with Vite.
| Feature | Vite | Webpack | esbuild |
|---|---|---|---|
| Dev server startup | ~300ms | ~3-10s | N/A (no dev server) |
| HMR speed | Instant | 1-5s | N/A |
| Production build | Fast (uses esbuild) | Medium | Fastest |
| Configuration | Minimal | Complex | Minimal |
| Plugin ecosystem | Growing | Massive | Small |
| Learning curve | Low | High | Low |
| Best for | New projects | Complex legacy | Libraries, speed |
Vite ("fast" in French) uses native ES modules during development and esbuild for production builds.
Development:
Production:
npm create vite@latest my-app -- --template react-ts
cd my-app
npm install
npm run dev
// vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [react()],
server: {
port: 3000,
open: true,
},
build: {
outDir: 'dist',
sourcemap: true,
minify: 'esbuild', // or 'terser' for smaller bundles
},
resolve: {
alias: {
'@': '/src',
},
},
});
Webpack is the most configurable bundler with the largest ecosystem.
npm init -y
npm install webpack webpack-cli webpack-dev-server -D
npm install html-webpack-plugin -D
// webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode: 'development',
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[contenthash].js',
clean: true,
},
devServer: {
port: 3000,
hot: true,
open: true,
},
module: {
rules: [
{
test: /\.(js|jsx|ts|tsx)$/,
exclude: /node_modules/,
use: 'babel-loader',
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.(png|svg|jpg|jpeg|gif)$/i,
type: 'asset/resource',
},
],
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
}),
],
resolve: {
extensions: ['.js', '.jsx', '.ts', '.tsx'],
alias: {
'@': path.resolve(__dirname, 'src'),
},
},
};
esbuild is written in Go and is 10-100x faster than JavaScript-based bundlers.
npm install esbuild -D
// build.js
const esbuild = require('esbuild');
esbuild.build({
entryPoints: ['src/index.tsx'],
bundle: true,
minify: true,
sourcemap: true,
outfile: 'dist/bundle.js',
target: ['es2020'],
loader: {
'.tsx': 'tsx',
'.ts': 'ts',
},
}).catch(() => process.exit(1));
# Simple bundle
npx esbuild src/index.ts --bundle --outfile=dist/bundle.js
# Production build
npx esbuild src/index.ts --bundle --minify --sourcemap --outfile=dist/bundle.js
# Watch mode
npx esbuild src/index.ts --bundle --watch --outfile=dist/bundle.js
Bundling a medium React app (~50 components):
| Tool | Dev startup | Production build |
|---|---|---|
| Vite | 300ms | 8s |
| Webpack 5 | 4.2s | 25s |
| esbuild | N/A | 0.4s |
Times are approximate and vary by hardware and project size.
# Install Vite
npm install vite @vitejs/plugin-react -D
# Create vite.config.ts
# Update package.json scripts
# Remove webpack dependencies
# Test and fix import issues
Common issues:
import.meta.env# Remove CRA
npm uninstall react-scripts
# Install Vite
npm install vite @vitejs/plugin-react -D
# Move index.html to root
# Update scripts in package.json
# Replace process.env with import.meta.env
// vite.config.ts
import { defineConfig } from 'vite';
export default defineConfig({
build: {
rollupOptions: {
input: {
main: 'index.html',
admin: 'admin.html',
},
},
},
});
// webpack.config.js
module.exports = {
optimization: {
splitChunks: {
chunks: 'all',
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all',
},
},
},
},
};
const esbuild = require('esbuild');
const { sassPlugin } = require('esbuild-sass-plugin');
esbuild.build({
entryPoints: ['src/index.tsx'],
bundle: true,
plugins: [sassPlugin()],
outfile: 'dist/bundle.js',
});
All three tools can minify JavaScript. For additional optimization or debugging minified code, use the JS Minifier to compare output sizes or the CSS Minifier for stylesheets.
Start new project?
├── Yes → Use Vite
└── No → Existing Webpack project?
├── Yes → Keep Webpack (migrate only if pain points)
└── No → Building a library?
├── Yes → Consider esbuild
└── No → Use Vite
Use these codefunc tools alongside this guide:
Vite is the default choice for new frontend projects in 2026. It combines excellent developer experience with fast production builds. Keep Webpack for complex existing projects or when you need specific plugins. Use esbuild directly for libraries or when raw build speed is critical. Don't migrate a working Webpack setup unless you have specific pain points.
Shrink SVG icons for the web — strip comments and whitespace, choose inline vs data URLs, and know when you still need a full SVGO pipeline.
Why compact GraphQL queries hurt reviews, how to format selection sets consistently, and a browser workflow before you paste into Apollo or GraphiQL.
A practical guide to Chrome DevTools for frontend developers — inspecting elements, debugging JavaScript, analyzing network requests, profiling performance, and workflows that save hours of debugging time.
Find a developer tool