Processing CSS and JavaScript in Eleventy

Eleventy’s philosophy of minimalism is both its strength and its challenge. It gives you full control over how to build your site but leaves most decisions up to you. Nowhere is this clearer than in how you handle CSS and JavaScript. Eleventy doesn’t prescribe a build pipeline; it simply exposes a few hooks and leaves you to decide how much structure you want.

Over time, developers have filled that gap in a variety of ways. Some prefer to let Eleventy do almost nothing beyond copying files. Others layer in full build systems like Gulp or Vite. Between those extremes lies a spectrum of approaches, each offering a different balance of simplicity, performance, and integration.

This piece walks through that spectrum, explaining where each approach fits. It ends with the Template Asset Pipeline plugin – a project inspired by Max Böck’s Eleventy Asset Pipeline – which aims to integrate traditional asset workflows into Eleventy’s build system without resorting to a separate toolchain.


The Spectrum of Approaches

Asset handling in Eleventy runs from “copy everything as-is” to “delegate everything to a dedicated bundler.” Each step along that line trades simplicity for sophistication.


1. Passthrough Copy

The simplest case is to do nothing at all. You tell Eleventy to copy your CSS and JS files directly into the output folder, untouched. This is enough for small projects or when you’re already writing browser-ready code. It builds instantly and has no dependencies, but you lose out on minification, bundling, and cache busting.

Eleventy’s documentation on Passthrough Copy explains how to configure it.


2. External Build Tools

Many developers reach for external tools like Gulp, npm scripts, or esbuild. These run in parallel with Eleventy rather than through it. They suit teams who already have established pipelines or want to share the same asset setup across projects.

The main advantage is flexibility – you can use any tool that runs in Node. The downside is coordination. You end up juggling multiple processes, and if one fails or finishes late, the others don’t always know.

Resources worth reading:


3. Custom Template Types

A more integrated approach is to teach Eleventy how to process CSS or JS directly by adding new template types. For example, you can register .scss as a format and run each file through Sass when Eleventy builds.

This brings asset compilation inside Eleventy’s lifecycle, so changes trigger automatic rebuilds and dependency tracking. It’s elegant once set up, but it requires familiarity with Eleventy’s internals and its data cascade.

See the Eleventy documentation on custom template types for examples.


4. The Bundle Plugin

From version 3 onwards, Eleventy introduced the official Bundle plugin. It collects snippets of CSS and JS defined throughout your templates, combines them into bundles, and injects them into the rendered pages.

It’s particularly effective for component-based architectures or when using WebC, where each component might define its own styles. Bundling happens per page, giving you only the assets you need. The trade-off is that it’s not meant for processing entire files or running through preprocessors – it’s about aggregation, not transformation.


5. Vite Integration

At the other end of the spectrum is Eleventy’s Vite plugin, which brings a full modern bundler and development server into the mix. You get hot module replacement, TypeScript and JSX support, and the full Vite plugin ecosystem.

It’s ideal for complex or app-like projects but can feel heavy for simple static sites. Build times increase, and configuration becomes more involved. Still, for teams already using Vite elsewhere, it offers the smoothest developer experience.


The Template Asset Pipeline Plugin

The Template Asset Pipeline plugin sits comfortably between these worlds. It was inspired by Max Böck’s original article on integrating asset processing into Eleventy, but it builds on the idea by using Eleventy’s own JavaScript template system to process assets as part of the normal build.

The idea is straightforward: treat CSS and JS files like templates. Instead of running a separate build tool, you register processors inside Eleventy itself. These processors can call PostCSS, Sass, esbuild, Webpack, or any other Node-based transformer, but they do so within Eleventy’s dependency graph. That means assets rebuild only when their sources change, and everything happens through a single eleventy command.

How It Works

When the plugin runs, it scans your source directories for asset files. Each file is passed to a processing function you define – for example, one that compiles Sass or runs PostCSS with plugins like Autoprefixer and cssnano. The results are written to your output folder and added to an Eleventy collection, so you can loop through them in templates or output links automatically.

Because the assets are handled as Eleventy templates, dependency tracking and rebuilds happen automatically. In production mode, you can minify or optimise; in development, you can skip those steps for faster feedback. It’s a familiar workflow, just unified under Eleventy’s build system.

Why It’s Useful

The plugin works well when you have existing asset files and want them processed inside Eleventy rather than through external scripts. It’s flexible enough to handle both CSS and JS, supports multiple processors, and reduces the overhead of coordinating parallel build tasks.

In practice, it replaces a web of npm scripts and file watchers with a single command. You can even combine it with other approaches – for example, using the Template Asset Pipeline for global styles and the Bundle plugin for per-component styles.

For installation and detailed configuration options, see the plugin documentation on GitHub.


When to Use It

The Template Asset Pipeline plugin is most useful when:

  • You have standalone CSS or JS files that need preprocessing or bundling
  • You want to use PostCSS, Sass, or Webpack without maintaining a parallel task runner
  • You prefer a single Eleventy build step that handles everything
  • You need production and development modes with different optimisation levels

It’s not the best fit for fully componentised architectures (the Bundle plugin handles those better) or projects already tied to a sophisticated bundler like Vite. But for the majority of Eleventy sites, it strikes a practical balance between simplicity and capability.


Where It Fits in the Eleventy Ecosystem

Eleventy is gradually evolving from a purely static site generator into a more flexible build framework. The introduction of WebC, the Bundle plugin, and the Vite integration reflects that shift. Each tool tackles a different part of the build problem – from component scoping to live reloading – but they share the same intent: to bring more of the modern web development workflow inside Eleventy itself.

The Template Asset Pipeline plugin follows that trajectory. It’s not trying to compete with Vite or WebC; instead, it fills the space between them. It provides a middle ground for projects that need real preprocessing and optimisation but want to stay close to Eleventy’s file-based, data-driven model.

In that sense, it captures what Eleventy has always done best: giving developers choices without forcing a single approach.


Further Reading


Links

  • [[2025-W45]]