BYU–Idaho • WDD 331R • Advanced CSS

Lightning CSS Setup

In the Build Tooling reading, you learned why CSS build tools exist and how Lightning CSS works as a single, all-in-one compiler. This page is the hands-on follow-up.

Overview

Install Lightning CSS, run a build command that bundles, prefixes, and minifies your CSS in one pass, and verify the output.

If you have limited experience with Node.js or the command line, do not worry. This page walks through every step. One of the advantages of Lightning CSS is how little setup it requires compared to plugin-based tools.

By the end you will have a working build that you can reuse in future assignments.

Starter Files

Download the CSS Bundling starter files and extract them into your Practice Site at unit-2/lightning-css-demo/. The zip contains an index.html page and a css/ directory with the layered architecture you learned in the CSS Architecture reading. All the CSS is already written and working.

Your job is not to write CSS on this page. It is to set up a build tool that bundles it.

[unit-2/lightning-css-demo]
├── css/
│   ├── base/
│   │   ├── elements.css
│   │   └── reset.css
│   ├── components/
│   │   └── card.css
│   ├── layout/
│   │   ├── chrome.css
│   │   └── primary.css
│   ├── tokens/
│   │   ├── colors.css
│   │   └── variables.css
│   ├── utilities/
│   │   └── utilities.css
│   └── main.css
└── index.html

Installing Node.js

Lightning CSS is distributed as an npm package, so you need Node.js installed. If you already have Node from a previous course or project, you can skip this section.

Open your terminal and run:

node --version

If you see a version number like v20.x.x or higher, you are good to go. If the command is not recognized, download and install the LTS version from nodejs.org. After installing, close and reopen your terminal, then verify again.

Initializing the Project

Navigate to your unit-2/lightning-css-demo/ directory in the terminal. Create a package.json file by running:

npm init -y

The -y flag accepts all the defaults so you do not have to answer a series of questions. If you prefer pnpm and already have it installed, you may use pnpm init instead.

Add a .gitignore File

Before you install anything, create a .gitignore file in unit-2/lightning-css-demo/ with this content:

node_modules/

The node_modules/ directory is where Node stores installed packages. It can contain thousands of files and should never be committed to your repository. The .gitignore file tells Git to skip it. If you already have a root .gitignore covering node_modules/, that's fine, but adding one here is a good habit.

Installing Lightning CSS

Install two packages: Lightning CSS itself, and a file watcher for automatic rebuilds during development.

npm install --save-dev lightningcss-cli chokidar-cli

If you are using pnpm, replace npm install with pnpm add.

Unlike PostCSS, which relies on a pipeline of separate plugins, Lightning CSS handles bundling, vendor prefixing, minification, and syntax lowering in one package. There is no config file to create and no plugins to choose between. Everything is controlled by command-line flags.

Adding a Build Script

Open your package.json and replace the default test script with this build command:

"scripts": {
    "build": "lightningcss --bundle --minify --targets \">= 0.25%\" css/main.css -o dist/styles.css",
    "watch": "chokidar \"css/**/*.css\" -c \"npm run build\" --debounce 600"
}

This single command does everything. Here is what each flag does:

Now run the build:

npm run build

If everything is set up correctly, you will see a new dist/ directory containing styles.css. Open that file and you should see all imports inlined, vendor prefixes added where needed, and the content minified.

Switching to the Bundled File

Update your index.html stylesheet link to use the bundled output instead of the source entry file:

<!-- Before: multi-file with @import -->
<link rel="stylesheet" href="css/main.css">
<!-- After: single bundled file -->
<link rel="stylesheet" href="dist/styles.css">

Refresh the page. It should look exactly the same, but the browser network panel should show a single request for styles.css instead of separate CSS files.

Understanding What the Flags Did

Try removing flags one at a time and rebuilding.

Without --minify

The output will still be bundled and prefixed, but it remains readable and retains whitespace and comments.

Without --bundle

The output contains only the minified contents of main.css, with @import statements still present. The browser would still need to fetch those files separately.

Without --targets

Lightning CSS skips vendor prefixing and syntax lowering. Modern CSS ships as-is, which may be fine for cutting-edge browsers but less compatible with older ones.

Development Workflow

You now have two versions of your CSS: the source files in css/ and the bundled output in dist/. Running npm run build manually every time is tedious, so use the watch script instead.

Lightning CSS does not have built-in watch mode, but chokidar-cli does. It watches your files and reruns the command when a change occurs.

npm run watch

Leave it running while you edit CSS. Every time you save a file inside css/, chokidar waits 600ms and rebuilds automatically.

Using npx Without a Local Install

If you want to run Lightning CSS once without installing it locally, use:

npx lightningcss-cli --bundle --minify --targets ">= 0.25%" css/main.css -o dist/styles.css

This is useful for quick experiments, but a local package.json is more reliable for a real project.

Comparing Lightning CSS to PostCSS

Both tools can produce the same bundled stylesheet, but their setup differs:

PostCSS gives more control and plugin flexibility. Lightning CSS gives speed and simplicity.

Final File Structure

[unit-2/lightning-css-demo]
├── css/
│   ├── base/
│   │   ├── elements.css
│   │   └── reset.css
│   ├── components/
│   │   └── card.css
│   ├── layout/
│   │   ├── chrome.css
│   │   └── primary.css
│   ├── tokens/
│   │   ├── colors.css
│   │   └── variables.css
│   ├── utilities/
│   │   └── utilities.css
│   └── main.css
├── dist/
│   └── styles.css
├── node_modules/
├── .gitignore
├── index.html
└── package.json

Notice there is no config file. One fewer file to maintain compared to a PostCSS setup. The file watcher is configured entirely in package.json.

Resources

Teaching Video Checklist

Back to Home