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 installfor this project.
Notes for Local Development
This issue only affects CI runners and clean environments. Local development machines are generally unaffected because:
node_modulespersist 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