Skip to main content
All Docs
Getting StartedBlockManOSUpdated March 26, 2026

Engineering: Fixing lightningcss Native Binary Resolution in CI

Engineering: Fixing lightningcss Native Binary Resolution in CI

Release: v1.0.49 · Patch
Merged: PR #45 (SHA: dbb9bf138428d7492335dd4820c1509a222cda9e)


Background

BlockManOS uses Tailwind CSS v4, which internally relies on lightningcss (via @tailwindcss/postcss) for CSS transformation. lightningcss is a Rust-based tool that ships pre-compiled, platform-specific native Node.js binaries as optional npm dependencies — for example, lightningcss-linux-x64-gnu for Linux x64 runners.

The Problem

CI builds on GitHub Actions (Linux x64 runners) began failing with:

Error: Cannot find module '../lightningcss.linux-x64-gnu.node'

This error occurs when npm does not install the optional platform-specific binary for the current environment. This is a known npm behaviour (see npm/cli#4828): when a package-lock.json is present and node_modules already exist (e.g. from a cache), npm may skip resolving optional dependencies, leaving the native binary absent.

An earlier workaround — deleting only package-lock.json — was not sufficient. If a stale or partial node_modules directory persisted, npm would still bypass the optional dependency installation step.

The Fix

The CI workflow (.github/workflows/ci.yml) was updated with two targeted changes:

1. Full Clean Install

Both package-lock.json and node_modules are now removed before installation:

rm -f package-lock.json && rm -rf node_modules

This guarantees npm performs a fresh dependency resolution from scratch, with no stale state that could cause it to skip optional packages.

2. Explicit Optional Dependency Installation

npm install is replaced with:

npm install --include=optional

The --include=optional flag explicitly instructs npm to install all optional dependencies, regardless of any environment heuristics. This ensures lightningcss-linux-x64-gnu (and any other platform-specific optional binary) is always present on the CI runner.

Updated CI Step

- uses: actions/setup-node@v4
  with:
    node-version: 20
# Delete package-lock.json and node_modules to force a clean install.
# This ensures npm resolves the correct platform-specific lightningcss
# native binary (lightningcss-linux-x64-gnu) for the CI runner.
- run: rm -f package-lock.json && rm -rf node_modules
- run: npm install --include=optional
- run: npm run build --if-present
- run: npx vitest run --passWithNoTests

Impact

  • No functional code changes — this fix is isolated to the CI pipeline configuration.
  • CI builds now complete successfully on Linux x64 runners with Tailwind CSS v4 and lightningcss.
  • The same pattern should be applied to any other CI environment or Docker-based build step that runs npm install for this project.

Notes for Local Development

This issue only affects CI runners and clean environments. Local development machines are generally unaffected because:

  • node_modules persist between runs.
  • npm typically installs optional dependencies correctly on a developer's native platform during initial npm install.

If you do encounter this error locally (e.g. after switching machines or architectures), running the following will resolve it:

rm -rf node_modules package-lock.json
npm install --include=optional