Claude-skill-registry esbuild
Configures esbuild for extremely fast JavaScript/TypeScript bundling with plugins, code splitting, and build optimization. Use when building libraries, rapid prototyping, or optimizing build performance.
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/esbuild" ~/.claude/skills/majiayu000-claude-skill-registry-esbuild && rm -rf "$T"
manifest:
skills/data/esbuild/SKILL.mdsource content
esbuild
Extremely fast JavaScript/TypeScript bundler written in Go, 10-100x faster than traditional bundlers.
Quick Start
npm install --save-dev esbuild # Bundle for browser npx esbuild src/index.ts --bundle --outfile=dist/bundle.js # Production build npx esbuild src/index.ts --bundle --minify --outfile=dist/bundle.js # Development with watch npx esbuild src/index.ts --bundle --watch --outfile=dist/bundle.js
API Usage
Build API
// build.js import * as esbuild from 'esbuild'; await esbuild.build({ entryPoints: ['src/index.ts'], bundle: true, minify: true, sourcemap: true, target: ['es2020'], outfile: 'dist/bundle.js', }); console.log('Build complete!');
Context API (Watch/Serve)
import * as esbuild from 'esbuild'; const ctx = await esbuild.context({ entryPoints: ['src/index.tsx'], bundle: true, outdir: 'dist', sourcemap: true, }); // Watch mode await ctx.watch(); console.log('Watching for changes...'); // Dev server await ctx.serve({ servedir: 'dist', port: 3000, }); console.log('Server running at http://localhost:3000');
Transform API
import * as esbuild from 'esbuild'; // Transform code without bundling const result = await esbuild.transform(code, { loader: 'tsx', target: 'es2020', minify: true, }); console.log(result.code);
Configuration Options
Browser Build
await esbuild.build({ entryPoints: ['src/index.tsx'], bundle: true, outfile: 'dist/bundle.js', // Target browsers target: ['chrome90', 'firefox88', 'safari14', 'edge90'], // Platform platform: 'browser', // Module format format: 'esm', // 'iife', 'cjs', 'esm' // Minification minify: true, minifyWhitespace: true, minifyIdentifiers: true, minifySyntax: true, // Source maps sourcemap: true, // 'linked', 'inline', 'external', 'both' // Tree shaking treeShaking: true, // Define globals define: { 'process.env.NODE_ENV': '"production"', }, // Legal comments legalComments: 'none', // 'inline', 'external', 'linked', 'none' });
Node.js Build
await esbuild.build({ entryPoints: ['src/server.ts'], bundle: true, outfile: 'dist/server.js', platform: 'node', target: 'node20', format: 'esm', // Externalize node_modules packages: 'external', // Or specify externals external: ['express', 'pg'], // Node.js banner for ESM banner: { js: "import { createRequire } from 'module'; const require = createRequire(import.meta.url);", }, });
Multiple Entry Points
await esbuild.build({ entryPoints: { main: 'src/index.ts', worker: 'src/worker.ts', admin: 'src/admin.ts', }, bundle: true, outdir: 'dist', // Code splitting splitting: true, format: 'esm', // Chunk naming chunkNames: 'chunks/[name]-[hash]', entryNames: '[name]-[hash]', assetNames: 'assets/[name]-[hash]', });
Loaders
Built-in Loaders
await esbuild.build({ entryPoints: ['src/index.tsx'], bundle: true, outdir: 'dist', loader: { '.tsx': 'tsx', '.ts': 'ts', '.jsx': 'jsx', '.js': 'js', '.json': 'json', '.css': 'css', '.svg': 'dataurl', '.png': 'file', '.woff2': 'file', }, });
Asset Handling
loader: { // Inline as data URL '.svg': 'dataurl', '.png': 'dataurl', // Copy to output directory '.woff': 'file', '.woff2': 'file', // Base64 inline '.small-icon': 'base64', // Raw text '.txt': 'text', // Copy without processing '.pdf': 'copy', }
Plugins
Plugin Structure
const myPlugin = { name: 'my-plugin', setup(build) { // Filter for matching files build.onResolve({ filter: /\.special$/ }, (args) => { return { path: path.resolve(args.resolveDir, args.path), namespace: 'special', }; }); // Load file content build.onLoad({ filter: /.*/, namespace: 'special' }, async (args) => { const content = await fs.readFile(args.path, 'utf8'); return { contents: `export default ${JSON.stringify(content)}`, loader: 'js', }; }); // Build lifecycle hooks build.onStart(() => { console.log('Build starting...'); }); build.onEnd((result) => { console.log(`Build finished with ${result.errors.length} errors`); }); }, }; await esbuild.build({ plugins: [myPlugin], // ... });
Environment Variables Plugin
import 'dotenv/config'; const envPlugin = { name: 'env', setup(build) { build.onResolve({ filter: /^env$/ }, (args) => ({ path: args.path, namespace: 'env-ns', })); build.onLoad({ filter: /.*/, namespace: 'env-ns' }, () => ({ contents: JSON.stringify(process.env), loader: 'json', })); }, };
SVG as React Component
import fs from 'fs'; import path from 'path'; const svgPlugin = { name: 'svg', setup(build) { build.onLoad({ filter: /\.svg$/ }, async (args) => { const svg = await fs.promises.readFile(args.path, 'utf8'); const name = path.basename(args.path, '.svg'); return { contents: ` export default function ${name}(props) { return ( <svg {...props} dangerouslySetInnerHTML={{ __html: ${JSON.stringify(svg)} }} /> ); } `, loader: 'jsx', }; }); }, };
Sass Plugin
import * as sass from 'sass'; const sassPlugin = { name: 'sass', setup(build) { build.onLoad({ filter: /\.scss$/ }, async (args) => { const result = sass.compile(args.path); return { contents: result.css, loader: 'css', }; }); }, };
Development Server
import * as esbuild from 'esbuild'; import http from 'http'; const ctx = await esbuild.context({ entryPoints: ['src/index.tsx'], bundle: true, outdir: 'dist', sourcemap: true, }); // Built-in server const { host, port } = await ctx.serve({ servedir: 'dist', port: 3000, }); // Or with custom proxy const proxy = http.createServer((req, res) => { const options = { hostname: host, port: port, path: req.url, method: req.method, headers: req.headers, }; const proxyReq = http.request(options, (proxyRes) => { res.writeHead(proxyRes.statusCode, proxyRes.headers); proxyRes.pipe(res, { end: true }); }); req.pipe(proxyReq, { end: true }); }); proxy.listen(8000);
Build Scripts
package.json
{ "scripts": { "build": "node build.js", "dev": "node dev.js", "typecheck": "tsc --noEmit" } }
Production Build
// build.js import * as esbuild from 'esbuild'; const isProduction = process.env.NODE_ENV === 'production'; await esbuild.build({ entryPoints: ['src/index.tsx'], bundle: true, outdir: 'dist', minify: isProduction, sourcemap: isProduction ? 'linked' : true, target: ['es2020'], define: { 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV), }, metafile: true, }).then((result) => { // Analyze bundle console.log( esbuild.analyzeMetafileSync(result.metafile) ); });
TypeScript
esbuild transpiles TypeScript but doesn't type-check:
await esbuild.build({ entryPoints: ['src/index.ts'], bundle: true, outfile: 'dist/bundle.js', // TypeScript options tsconfig: 'tsconfig.json', // JSX factory jsx: 'automatic', jsxImportSource: 'react', // Or transform jsx: 'transform', jsxFactory: 'React.createElement', jsxFragment: 'React.Fragment', });
Run type-checking separately:
# In parallel npx tsc --noEmit & node build.js
See references/plugins.md for community plugins and references/recipes.md for common patterns.