# How Impeccable Implements Static Site Generation with Bun’s Bundler

> Discover how Impeccable leverages Bun's bundler with native Bun.build API to create production-ready static sites from HTML entry points and compiled Tailwind CSS.

- Repository: [Paul Bakaus/impeccable](https://github.com/pbakaus/impeccable)
- Tags: how-to-guide
- Published: 2026-03-09

---

**Impeccable generates its static site by orchestrating Tailwind CSS compilation with the native `Bun.build` API in [`scripts/build.js`](https://github.com/pbakaus/impeccable/blob/main/scripts/build.js), bundling HTML entry points into a production-ready `build/` directory with minified assets and linked source maps.**

The [pbakaus/impeccable](https://github.com/pbakaus/impeccable) repository leverages Bun’s lightning-fast bundler to convert vanilla JavaScript and Tailwind CSS into a fully static, edge-deployable website. This analysis examines the exact implementation in the build script, revealing how the project handles CSS preprocessing, HTML bundling, and asset optimization within a single Node-style pipeline.

## The Four-Phase Build Pipeline

Impeccable’s static site generation follows a strict sequence defined in [`scripts/build.js`](https://github.com/pbakaus/impeccable/blob/main/scripts/build.js). Each phase addresses specific constraints of modern static site generation, from Tailwind directive processing to stable URL preservation for SEO.

### Phase 1: Pre-compiling Tailwind CSS

Before invoking the bundler, the script must handle Tailwind CSS separately. Bun’s native CSS bundler cannot process Tailwind’s `@theme` directive, so the pipeline first executes the Tailwind CLI to compile [`public/css/main.css`](https://github.com/pbakaus/impeccable/blob/main/public/css/main.css) into production-ready [`public/css/styles.css`](https://github.com/pbakaus/impeccable/blob/main/public/css/styles.css).

```bash

# Executed within scripts/build.js

bunx @tailwindcss/cli -i public/css/main.css -o public/css/styles.css --minify

```

This preprocessing step ensures that by the time `Bun.build` runs, all CSS is standard-compliant and ready for bundler optimization.

### Phase 2: HTML Entry Point Bundling with Bun.build

The core static site generation logic lives in the `buildStaticSite` function (lines 79-106 of [`scripts/build.js`](https://github.com/pbakaus/impeccable/blob/main/scripts/build.js)). This function wraps the native `Bun.build` API, configuring it to treat HTML files as entry points and traverse their JavaScript dependencies automatically.

```javascript
// scripts/build.js – static site generation core
async function buildStaticSite() {
  const entrypoints = [
    path.join(ROOT_DIR, 'public', 'index.html'),
    path.join(ROOT_DIR, 'public', 'cheatsheet.html'),
  ];
  const outdir = path.join(ROOT_DIR, 'build');

  console.log('📦 Building static site with Bun...');
  const result = await Bun.build({
    entrypoints,
    outdir,
    minify: true,
    sourcemap: 'linked',
  });

  // Error handling and results processing follow...
}

```

The configuration targets two HTML files—[`public/index.html`](https://github.com/pbakaus/impeccable/blob/main/public/index.html) and [`public/cheatsheet.html`](https://github.com/pbakaus/impeccable/blob/main/public/cheatsheet.html)—and directs all output to the `build/` directory. Setting `minify: true` enables JavaScript and CSS minification, while `sourcemap: 'linked'` generates external source maps that preserve debugging capabilities without inflating production asset sizes.

### Phase 3: Copying Static Assets with Stable URLs

After bundling completes, the script copies specific files requiring unhashed filenames into the `build/` directory. These include SEO-critical assets like `og-image.jpg` and [`robots.txt`](https://github.com/pbakaus/impeccable/blob/main/robots.txt) that must maintain predictable URLs for social media crawlers and search engine bots.

### Phase 4: Build Metrics and Pipeline Continuation

Finally, the script logs quantitative metrics—file counts for HTML, JavaScript, and CSS alongside total bundle size—before passing control to subsequent Impeccable pipeline stages. These later steps include skill transforms, ZIP archive generation, and Cloudflare Pages deployment preparation.

## Local Development and Execution

To reproduce Impeccable’s static site generation locally, ensure Bun is installed and execute the build command:

```bash

# Install Bun if not present

curl -fsSL https://bun.sh/install | bash

# Install project dependencies

bun install

# Execute the full build pipeline

bun run build

```

The terminal output demonstrates the two-phase bundling process:

```

🎨 Building Tailwind CSS...
✓ Tailwind CSS compiled

📦 Building static site with Bun...
✓ Static site built to ./build/
  HTML: 1 file
  JS: 3 file(s) (45.2 KB)
  CSS: 1 file(s) (12.8 KB)
  Total: 58.0 KB

```

The resulting `build/` folder contains self-contained, minified assets compatible with any static hosting provider.

## Key Files in the Architecture

Understanding Impeccable’s implementation requires familiarity with these specific source files:

- **[`scripts/build.js`](https://github.com/pbakaus/impeccable/blob/main/scripts/build.js)**: Contains the `buildStaticSite` function that orchestrates `Bun.build` and manages the four-phase pipeline.
- **[`public/index.html`](https://github.com/pbakaus/impeccable/blob/main/public/index.html)**: Primary HTML entry point bundled by Bun, serving as the main documentation landing page.
- **[`public/cheatsheet.html`](https://github.com/pbakaus/impeccable/blob/main/public/cheatsheet.html)**: Secondary entry point for the design system reference, processed simultaneously with the index.
- **[`public/css/main.css`](https://github.com/pbakaus/impeccable/blob/main/public/css/main.css)**: Tailwind source file containing `@theme` directives, compiled prior to bundling because Bun’s CSS parser does not support Tailwind-specific syntax.

## Summary

- **Impeccable uses a hybrid approach in [`scripts/build.js`](https://github.com/pbakaus/impeccable/blob/main/scripts/build.js)** that combines Tailwind CLI preprocessing with Bun’s native bundler to generate static sites.
- **The `buildStaticSite` function wraps `Bun.build`** to process [`public/index.html`](https://github.com/pbakaus/impeccable/blob/main/public/index.html) and [`public/cheatsheet.html`](https://github.com/pbakaus/impeccable/blob/main/public/cheatsheet.html) as entry points, emitting minified assets to the `build/` directory.
- **Tailwind CSS requires separate compilation** via `bunx @tailwindcss/cli` because Bun’s CSS bundler cannot handle the `@theme` directive.
- **Static assets with stable URLs are copied post-bundle** to preserve SEO-critical paths for images and [`robots.txt`](https://github.com/pbakaus/impeccable/blob/main/robots.txt).
- **The `Bun.build` configuration uses `sourcemap: 'linked'` and `minify: true`** to balance production performance with debugging capabilities.

## Frequently Asked Questions

### Why does Impeccable compile Tailwind CSS separately before running Bun.build?

Bun’s CSS bundler cannot parse Tailwind’s `@theme` directive and other Tailwind-specific syntax. According to the source code in [`scripts/build.js`](https://github.com/pbakaus/impeccable/blob/main/scripts/build.js), the build pipeline explicitly runs `bunx @tailwindcss/cli` to transform [`public/css/main.css`](https://github.com/pbakaus/impeccable/blob/main/public/css/main.css) into standard CSS before invoking `Bun.build`, ensuring compatibility with the bundler’s minification engine.

### What HTML entry points does Impeccable use for static site generation?

The `buildStaticSite` function in [`scripts/build.js`](https://github.com/pbakaus/impeccable/blob/main/scripts/build.js) (lines 79-106) configures `Bun.build` with two entry points: [`public/index.html`](https://github.com/pbakaus/impeccable/blob/main/public/index.html) for the primary documentation and [`public/cheatsheet.html`](https://github.com/pbakaus/impeccable/blob/main/public/cheatsheet.html) for the design system reference. Both files are processed in a single build operation, allowing Bun to deduplicate shared dependencies between pages.

### How does Impeccable handle source maps in production builds?

The implementation configures `Bun.build` with `sourcemap: 'linked'` rather than inline source maps. This setting generates separate `.map` files that enable debugging of minified code in production while keeping the actual JavaScript and CSS files small and cache-efficient for end users.

### Can the build output be deployed directly to Cloudflare Pages?

Yes. The `build/` directory produced by Impeccable’s static site generation contains fully bundled, minified assets with stable URLs for SEO-critical files. While the repository includes additional pipeline stages for skill transforms and ZIP creation, the static output itself is immediately deployable to Cloudflare Pages or any other static hosting platform.