Claude Code Plugins

Community-maintained marketplace

Feedback

jutsu-bun:bun-bundler

@TheBushidoCollective/han
38
0

Use when bundling JavaScript/TypeScript code with Bun's fast bundler. Covers building for different targets, tree-shaking, code splitting, and optimization strategies.

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name jutsu-bun:bun-bundler
description Use when bundling JavaScript/TypeScript code with Bun's fast bundler. Covers building for different targets, tree-shaking, code splitting, and optimization strategies.
allowed-tools Read, Write, Edit, Bash, Grep, Glob

Bun Bundler

Use this skill when bundling JavaScript/TypeScript applications with Bun's built-in bundler, which provides exceptional performance and modern features.

Key Concepts

Basic Bundling

Bun can bundle your code for different targets:

# Bundle for Bun runtime
bun build ./src/index.ts --outdir ./dist

# Bundle for browsers
bun build ./src/index.ts --outdir ./dist --target=browser

# Bundle for Node.js
bun build ./src/index.ts --outdir ./dist --target=node

# Minify output
bun build ./src/index.ts --outdir ./dist --minify

Programmatic API

Use Bun's build API in TypeScript:

import { build } from "bun";

await build({
  entrypoints: ["./src/index.ts"],
  outdir: "./dist",
  target: "bun",
  minify: true,
  sourcemap: "external",
});

Build Targets

Bun supports multiple build targets:

  • bun - Optimized for Bun runtime (default)
  • browser - Browser-compatible bundle
  • node - Node.js-compatible bundle

Output Formats

Control output format:

await build({
  entrypoints: ["./src/index.ts"],
  outdir: "./dist",
  format: "esm", // or "cjs", "iife"
});

Best Practices

Entry Points Configuration

Define multiple entry points for complex applications:

await build({
  entrypoints: [
    "./src/client/index.ts",
    "./src/server/index.ts",
    "./src/worker.ts",
  ],
  outdir: "./dist",
  naming: {
    entry: "[dir]/[name].[ext]",
    chunk: "[name]-[hash].[ext]",
    asset: "assets/[name]-[hash].[ext]",
  },
});

Tree Shaking

Bun automatically tree-shakes unused code:

// utils.ts
export function used() {
  return "used";
}

export function unused() {
  return "unused";
}

// index.ts
import { used } from "./utils";

console.log(used()); // Only 'used' function will be bundled

Code Splitting

Split code for better loading performance:

await build({
  entrypoints: ["./src/index.ts"],
  outdir: "./dist",
  splitting: true, // Enable code splitting
  target: "browser",
});

Environment Variables

Replace environment variables at build time:

await build({
  entrypoints: ["./src/index.ts"],
  outdir: "./dist",
  define: {
    "process.env.API_URL": JSON.stringify("https://api.example.com"),
    "process.env.NODE_ENV": JSON.stringify("production"),
  },
});

External Dependencies

Mark dependencies as external to exclude from bundle:

await build({
  entrypoints: ["./src/index.ts"],
  outdir: "./dist",
  external: ["react", "react-dom"], // Don't bundle React
  target: "browser",
});

Source Maps

Generate source maps for debugging:

await build({
  entrypoints: ["./src/index.ts"],
  outdir: "./dist",
  sourcemap: "external", // or "inline", "none"
  minify: true,
});

Common Patterns

Building a Library

// build.ts
import { build } from "bun";

// ESM build
await build({
  entrypoints: ["./src/index.ts"],
  outdir: "./dist/esm",
  format: "esm",
  target: "node",
  minify: true,
  sourcemap: "external",
});

// CJS build
await build({
  entrypoints: ["./src/index.ts"],
  outdir: "./dist/cjs",
  format: "cjs",
  target: "node",
  minify: true,
  sourcemap: "external",
});

console.log("Build complete!");

Building a Web Application

// build.ts
import { build } from "bun";

await build({
  entrypoints: ["./src/index.tsx"],
  outdir: "./dist",
  target: "browser",
  format: "esm",
  minify: true,
  splitting: true,
  sourcemap: "external",
  publicPath: "/assets/",
  naming: {
    entry: "[dir]/[name].[ext]",
    chunk: "[name]-[hash].[ext]",
    asset: "assets/[name]-[hash].[ext]",
  },
  define: {
    "process.env.NODE_ENV": JSON.stringify("production"),
  },
});

Building Multiple Outputs

// build.ts
import { build } from "bun";

const builds = [
  {
    entrypoints: ["./src/index.ts"],
    outdir: "./dist/esm",
    format: "esm" as const,
    target: "browser" as const,
  },
  {
    entrypoints: ["./src/index.ts"],
    outdir: "./dist/cjs",
    format: "cjs" as const,
    target: "node" as const,
  },
  {
    entrypoints: ["./src/index.ts"],
    outdir: "./dist/iife",
    format: "iife" as const,
    target: "browser" as const,
  },
];

for (const config of builds) {
  await build({
    ...config,
    minify: true,
    sourcemap: "external",
  });
}

console.log("All builds complete!");

Build Script with Watching

// watch-build.ts
import { watch } from "fs";
import { build } from "bun";

async function buildApp() {
  console.log("Building...");
  await build({
    entrypoints: ["./src/index.ts"],
    outdir: "./dist",
    target: "bun",
  });
  console.log("Build complete!");
}

// Initial build
await buildApp();

// Watch for changes
watch("./src", { recursive: true }, async (event, filename) => {
  console.log(`File changed: ${filename}`);
  await buildApp();
});

Plugin System

Create custom build plugins:

import type { BunPlugin } from "bun";

const myPlugin: BunPlugin = {
  name: "my-plugin",
  setup(build) {
    build.onLoad({ filter: /\.custom$/ }, async (args) => {
      const text = await Bun.file(args.path).text();
      return {
        contents: `export default ${JSON.stringify(text)}`,
        loader: "js",
      };
    });
  },
};

await build({
  entrypoints: ["./src/index.ts"],
  outdir: "./dist",
  plugins: [myPlugin],
});

Anti-Patterns

Don't Bundle Node Modules for Node Target

// Bad - Bundling all dependencies for Node
await build({
  entrypoints: ["./src/server.ts"],
  target: "node",
  // Missing external configuration
});

// Good - Mark dependencies as external
await build({
  entrypoints: ["./src/server.ts"],
  target: "node",
  external: ["express", "mongoose", "*"], // "*" excludes all node_modules
});

Don't Ignore Build Errors

// Bad - No error handling
await build({
  entrypoints: ["./src/index.ts"],
  outdir: "./dist",
});

// Good - Handle build errors
try {
  const result = await build({
    entrypoints: ["./src/index.ts"],
    outdir: "./dist",
  });

  if (!result.success) {
    console.error("Build failed");
    process.exit(1);
  }

  console.log("Build succeeded");
} catch (error) {
  console.error("Build error:", error);
  process.exit(1);
}

Don't Minify Development Builds

// Bad - Always minifying
await build({
  entrypoints: ["./src/index.ts"],
  outdir: "./dist",
  minify: true, // Hard to debug in development
});

// Good - Conditional minification
const isDev = Bun.env.NODE_ENV === "development";

await build({
  entrypoints: ["./src/index.ts"],
  outdir: "./dist",
  minify: !isDev,
  sourcemap: isDev ? "inline" : "external",
});

Don't Over-Split Code

// Bad - Excessive code splitting
await build({
  entrypoints: ["./src/index.ts"],
  outdir: "./dist",
  splitting: true,
  target: "bun", // Code splitting not needed for Bun target
});

// Good - Split only when beneficial
await build({
  entrypoints: ["./src/index.ts"],
  outdir: "./dist",
  splitting: true,
  target: "browser", // Beneficial for browsers
});

Related Skills

  • bun-runtime: Understanding Bun's runtime for target optimization
  • bun-package-manager: Managing build dependencies
  • bun-testing: Testing bundled code