Skip to content
CAI
Software that uses CAICheck a score

less/less.js

46.4

Weak · 1 October 2026

17.9k

lines of production code

JavaScript

primary language

2

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

What this system is

This system is the Less.js compiler, a tool that transforms Less stylesheet code into standard CSS for both browser and Node.js environments. It provides a command-line interface and a plugin architecture, supporting modern ES module structures alongside legacy compatibility layers. The codebase includes extensive infrastructure for benchmarking performance, automated release management, and comprehensive regression testing across various CSS features and parser behaviors.

How it got here

2010–2020 — Native ESM migration and legacy cleanup

18 changes.

The project underwent a comprehensive migration to native ES Modules, replacing the legacy prototype-based architecture with ES6 classes and removing deprecated entry points and parser implementations. This overhaul included restructuring the build system, updating the CLI, and modernizing core modules to improve code cleanliness and maintainability. Concurrently, governance documentation was updated, and benchmarking infrastructure was enhanced to track historical performance.

2025–2026 — Release automation and test expansion

7 changes.

This period focused on establishing a robust, PR-based release workflow with automated versioning and publishing scripts, replacing ad-hoc methods. Concurrently, the project significantly expanded its test suite, adding comprehensive coverage for Less.js regression, error handling, unit tests, and plugin functionality to ensure compiler stability.

Features

Historical benchmark infrastructure with version-specific test suites

The benchmarking tooling in packages/less/benchmark has been upgraded to support historical performance tracking across multiple Less versions. A new runner (benchmark-runner.js) and orchestration script (run-historical.sh) automate compilation tests against specific releases (v2.0.0 through v4.5.1) using isolated git worktrees. The suite now includes dedicated benchmark files for version-specific features: benchmark-v3.less for v3.0+ features like if() and property accessors, benchmark-v37.less for the each() function, and benchmark-v39.less for the range() function. Results are saved as structured JSON files in the results/ directory, capturing system metadata, version details, and statistical performance metrics.

packages/less/benchmark · high confidence

New PR-based release flow with automated version bumping and publishing scripts

The repository now uses a PR-based release workflow for both master and alpha branches, replacing previous ad-hoc publishing methods. New scripts in the \scripts/\ directory automate the process: \bump-and-publish.js\ validates that the version in \package.json\ (set by the release PR) is ahead of the published NPM version, creates an annotated git tag, and publishes packages without making local commits; \post-merge-version-fix.js\ restores alpha version numbers in \package.json\ after merging master into alpha to prevent overwrites; \publish-beta.js\ provides a local workflow to build, test, and publish beta releases with configurable NPM tags; and \release-metadata.js\ centralizes logic for parsing release PR titles, validating version constraints (e.g., alpha versions must follow X.Y.Z-alpha.N), and updating changelogs. A comprehensive test suite (\test-release-automation.js\) verifies the GitHub Actions workflow conditions and release logic.

scripts · high confidence

Removals

Removal of legacy Less.js node implementation

The entire legacy Less.js node implementation located in lib/less/node has been removed. This deletes all core AST node classes (including Call, Color, Dimension, Directive, Element, Expression, Keyword, Operation, Quoted, Rule, Ruleset, Selector, and Variable) and their associated logic for parsing, evaluation, and CSS generation. Users relying on this specific node-based parser and renderer will no longer have access to these components.

lib/less/node · high confidence

Removal of legacy lib/less.js entry point

The legacy lib/less.js file, which previously served as a simple module entry point, has been removed from the library. This change eliminates the previous initialization structure, aligning with the broader refactoring of the module system to improve code cleanliness and remove deprecated patterns.

lib · high confidence

Removal of legacy parser.js implementation

The legacy parser implementation located in lib/less/parser.js has been removed from the codebase. This file contained the original parsing logic, including the chunking mechanism, the token-matching functions (peek, $), and the initial entity and mixin parsers. Its deletion indicates a migration to a different parsing architecture or a refactored parser structure elsewhere in the library.

lib/less · high confidence

Behavioural changes

Automated post-merge version handling and pre-commit checks

The repository now includes a post-merge hook that automatically runs a script to preserve alpha versions when merging the master branch into the alpha branch, ensuring version consistency across branches. Additionally, a pre-commit hook has been added to enforce type checking within the 'packages/less' directory and run the full test suite before allowing commits.

.husky · high confidence

Browser Less.js runtime rewritten in ES modules

The browser-side Less.js runtime has been completely rewritten using ES modules (ESM) and native ES6 classes, replacing the previous prototype-based architecture. This change introduces a new modular structure in the \less-browser\ directory, separating concerns into distinct files for bootstrapping, default options, browser-specific utilities, caching, error reporting, and file management. The core CSS generation and AST traversal logic in \less/visitors\ has also been migrated to ES6 classes (e.g., \ExtendFinderVisitor\, \ImportVisitor\, \ToCSSVisitor\). For users, this modernizes the codebase but may require updates if custom plugins or extensions relied on the old prototype-based API or the previous internal module structure.

packages/less/lib/less-browser, packages/less/lib/less/visitors · high confidence

Build system migrated to native ESM with Rollup

The build process in packages/less/build has been rewritten to use native ESM and Rollup, replacing the previous bundling approach. This change introduces a new banner.js module for license headers and a rollup.js script that generates UMD bundles (less.js, less.min.js) for the browser and a CJS bundle (less-node.cjs) for Node.js, ensuring better compatibility with modern module systems while preserving version and license metadata in the output artifacts.

packages/less/build · high confidence

CLI rewritten in native ESM with new deprecation warning and plugin handling

The \lessc\ command-line tool has been rewritten as a native ES module (no build step), introducing support for the \--disable-plugin-rule\ flag and deferring deprecation warnings until after argument parsing to ensure they appear correctly in the output.

packages/less/bin · high confidence

Extracted shared ESLint base configuration

A new shared ESLint configuration file (config/eslint/base.cjs) has been introduced to standardize linting rules across the project. This base config enforces specific formatting and style rules, such as 4-space indentation, single quotes, and error handling for empty blocks, while explicitly disabling rules for constant conditions and conditional assignments to accommodate existing code patterns.

config · high confidence

Less.js package structure and tooling overhaul

The Less.js package has been restructured to support native ESM with a CJS compatibility layer, introducing dedicated entry points (\index.cjs\) and build configurations (\Gruntfile.cjs\, \tsconfig.json\). This change includes new ESLint configurations (\.eslintrc.cjs\, \.eslintignore\) to enforce code quality, updated npm packaging rules (\.npmignore\, \.gitignore\), and new development tooling scripts for coverage reporting (\scripts/coverage-lines.js\, \scripts/coverage-report.js\) and automated Playwright browser installation (\scripts/postinstall.js\). Additionally, the package now includes a \test.less\ file and a \test-import-module\ directory to support import testing, while the \README.md\ has been updated to reflect the new usage patterns.

packages/less · high confidence

Less.js v4.8.0: Native ESM, deprecated legacy syntax, and refactored core modules

The Less.js library in packages/less/lib/less has been migrated to native ES Modules with no build step, replacing the previous prototype-based tree nodes with ES6 classes. This release deprecates several legacy identifier forms and behaviors: bare @variable usage in non-value at-rule positions, dynamic @charset interpolation, mixin calls without parentheses, and the --math=always option (defaulting to parens-division). The deprecation registry now tracks these changes, and the core parsing, rendering, and import management logic has been refactored into distinct ES6 modules (contexts, import-manager, parse-tree, etc.) to support the new module system while maintaining backward compatibility for existing Less files.

packages/less/lib/less · high confidence

Migrate less-node to native ESM and replace image-size with probe-image-size

The less-node package has been rewritten to use native ES Modules (ESM) without a build step, replacing CommonJS require calls with dynamic imports via createRequire. This change introduces new ESM-compatible modules for environment configuration, file management, and plugin loading. Additionally, the image-size functionality now uses the probe-image-size library instead of the deprecated image-size package, allowing users to detect image dimensions via the image-size, image-width, and image-height functions with the newer dependency.

packages/less/lib/less-node · high confidence

Migrated Less.js core modules to native ESM

The Less.js library has been refactored to use native ES Modules (ESM) instead of CommonJS, removing the need for a build step. This change updates internal data files (such as color definitions and unit conversions) and environment abstractions (including file managers and plugin loaders) to use ES module syntax (import/export). For users, this means the library now relies on native ESM support in the runtime environment, potentially affecting compatibility with older bundlers or Node.js versions that do not fully support ESM without configuration.

packages/less/lib/less/data, packages/less/lib/less/environment · high confidence

Project governance and documentation overhaul

The repository has been restructured with a comprehensive update to its documentation and governance files. The README now features a modernized layout with status badges, links to the official website and Stack Overflow, and an auto-generated contributor table powered by the all-contributors tool. A detailed CONTRIBUTING.md guide has been added, outlining issue reporting, pull request standards, and the new automated release workflow. Additionally, standard configuration files have been introduced, including .editorconfig for consistent coding styles, .gitattributes and .gitignore for repository hygiene, .nvmrc to pin the Node.js version to v18, and a pnpm-workspace.yaml to define the monorepo structure. The project license has also been updated to Apache 2.0.

(repo-wide) · high confidence

Refactored Less.js functions to ES6 modules with runtime CSS variable support

The Less.js function library has been rewritten as native ES6 modules, splitting the previous monolithic implementation into distinct files for boolean, color, math, and other operations. This refactor introduces a critical fix for math functions (such as \sqrt\, \sin\, \cos\): when an argument is a runtime CSS variable (e.g., \var()\), these functions now pass the call through to the browser instead of throwing a compile-time error, provided the function has a CSS equivalent. Additionally, the \escape()\ function now prevents the re-parsing of its results, ensuring that percent-encoded characters are treated as literal CSS.

packages/less/lib/less/functions · high confidence

Support for bracket lookups in variable interpolation and deprecation of legacy identifier forms

The parser now supports \\[...\]\ lookups inside \@{...}\ interpolation (e.g., \@{map\[key\]}\), resolving previous issues where such syntax was emitted verbatim instead of being substituted. This change also deprecates bare \@variable\ references in non-value at-rule positions (requiring \@{variable}\ interpolation) and dynamic \@charset\ usage, while adding warnings for numeric-leading variable names and dash-only identifiers to prepare for Less 5.x removals.

packages/less/lib/less/parser · high confidence

Fixes

Tree nodes refactored to ES6 classes with JSDoc type annotations

The internal Less tree node classes (such as Anonymous, AtRule, Color, Declaration, and others in packages/less/lib/less/tree) have been converted from prototype-based structures to ES6 classes. This refactoring introduces JSDoc type annotations for improved type safety and developer experience, and includes specific behavioral fixes such as preventing the crash on nested @supports with dumpLineNumbers, avoiding reparsing of escape() results, and ensuring mixin calls used as property values are handled correctly without rendering as \[object Object\].

packages/less/lib/less/tree · high confidence

Test coverage

Added error-evaluation test cases for the Less compiler; Added test plugins for Less.js plugin system; Added test-data plugin fixtures for plugin system validation; Browser test suite infrastructure and fixtures; Expanded test data and configuration for Less.js regression testing; Expanded unit test coverage for CSS at-rules, color functions, and container queries.

Dependencies

Less.js v4.9.1 release with updated dependencies

This release updates the Less.js package to version 4.9.1 and refreshes its dependency tree. Key updates include upgrading \make-dir\ to v5.1.0 (addressing a security vulnerability), \needle\ to v3.5.0, \probe-image-size\ to v7.3.0, and \mime\ to v1.6.0. Build and test tooling dependencies such as \playwright\ (v1.50.1), \typescript\ (v5.7.0), and \eslint\ (v7.32.0) are also updated. The monorepo root now enforces \pnpm@9.15.9\ as the package manager.

(dependencies) · high confidence

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

How this codebase got here

Score

  • CAI 45 → 46 (+1.8)
  • Rubric changed (rubric-2026.09.11 → rubric-2026.09.18) — scores are not directly comparable.

Lenses

  • Code Health 36 → 36 (+0.0)
  • Architecture 81 → 79 (-2.6)
  • Maturity 58 → 58 (-0.5)
  • Readiness 51 → 48 (-3.0)
  • Security 46 → 56 (+9.7)
  • Performance 79 (new)

Resolved (6)

  • Documentation: no architecture or design documentation (README.md)
  • Documentation: no installation or build instructions (README.md)
  • Documentation: no usage examples (README.md)
  • Hotspot: packages/less/test/less-test.js (packages/less/test/less-test.js)
  • Medium CVE: [GHSA redacted] (pnpm-lock.yaml)
  • Off-boarding risk: anonymized user #1

New (7)

  • End-of-life runtime: Node.js 18
  • Low cohesion: Node (LCOM4 5) (packages/less/lib/less/tree/node.js)
  • Low cohesion: PluginManager (LCOM4 4) (packages/less/lib/less/plugin-manager.js)
  • Medium CVE: [GHSA redacted] (package-lock.json)
  • Medium CVE: [GHSA redacted] (pnpm-lock.yaml)
  • Off-boarding risk: anonymized user #1
  • Projects may be oversized for their cohesion

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

less/less.js was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.

About this page

  • The score is its most recent published measurement, taken on 1 October 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
  • Measured at commit 713331655e437401dfea6cd233893a69762734e1 — the exact code this score is about.
  • Scored under rubric-2026.09.18 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer preprod-e569280dd5e2.