Library / SDK
gruntjs/grunt-contrib-less avatar
gruntjs/grunt-contrib-less

grunt-contrib-less: compiling LESS to CSS inside a Grunt pipeline

Compile LESS files to CSS.

659 stars167 forksJavaScriptMIT

At a glance

What is it?
grunt-contrib-less is the Grunt task that compiles LESS stylesheets to CSS, exposing the LESS compiler's own options such as source maps, modifyVars, custom functions and math mode to the Gruntfile. It suits a team already running Grunt that wants LESS in the same build as its JS, and it is a thin wrapper around the less package rather than a compiler of its own.
Who is it for?
grunt-contrib-less fits a project that has already chosen Grunt and LESS and wants the stylesheet step in the same build as the JavaScript, with the compiler options exposed rather than hidden. It does not fit a team that has moved to a modern bundler, since the Grunt task is the tool and the LESS toolchain in general is the older one, and it does not suit a project that wants Sass or PostCSS.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 122 days ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A Grunt task that hands LESS options straight through

grunt-contrib-less does one thing: compile LESS files to CSS. The repository description is a single sentence, the README subtitle repeats it, and the package description in package.json is Compile LESS files to CSS.

What makes it more than a one line wrapper is the options surface. Almost every option in the LESS compiler is exposed directly, with the LESS documentation's own naming, and the defaults are the LESS defaults. That is the design decision: this task is a configuration adapter, not a reimplementation, so the LESS documentation is your reference and the Gruntfile is a place to set those same values.

The examples show the shape. A target declares options and files, and the files object maps an output path to a source path.

js
less: {
  development: {
    options: {
      paths: ['assets/css']
    },
    files: {
      'path/to/result.css': 'path/to/source.less'
    }
  },

The paths option deserves a note because it is the one people get wrong. It specifies directories to scan for @import directives when parsing, and the default value is the directory of the input file, which the README says is probably what you want. If you specify a function the source filepath will be the first argument, and you can return either a string or an array of paths.

The task is run with the grunt less command, and the README points at the Grunt guide on configuring tasks for how task targets, files and options may be specified, which is the general Grunt contract rather than anything specific to this plugin.

Source maps, modifyVars and custom functions, the three that matter

Three groups of options decide whether this task is useful for your project, and they are worth reading in the order the README lists them.

Source maps are the first, and there are six options that together control where the map goes and how it points back. sourceMap enables them, sourceMapFilename writes the map to a separate file with the given filename, sourceMapURL overrides the default URL that points to the source map from the compiled CSS file, sourceMapBasepath sets the base path for the less file paths in the source map, sourceMapRootpath adds a path onto those paths, and sourceMapFileInline puts the map, and any less files, into the output CSS file as a base64 data uri.

modifyVars is the second, and it is the mechanism for theming. It overrides global variables and is described as equivalent to the --modify-vars option in less on the command line. The usage example shows it in practice, with an imgPath pointing at a CDN and a bgColor set to red, which is exactly the use case of building the same stylesheet for a different environment without a second source file.

The third is customFunctions, which lets you define functions to be available within your LESS stylesheets. The function's name must be lowercase, the first argument is the less object, subsequent arguments are from the less function call, and the values passed are types defined within less while the return value may be either one of them or primitive.

There is also process, a function that receives the CSS content and the destination path, which lets the written CSS be parsed and passed through a function of your own before it lands on disk. That is the hook for a post-processing step without a second Grunt task.

Math and units, where LESS is looser than most people expect

The math option and its siblings are the part of the LESS configuration that most often causes confusion, and this task exposes all of it.

There is a strictMath option, marked deprecated and replaced by math, which when enabled requires math to be in parenthesis. The replacement is the math option, a string, and it defaults to parens-division, in which no division is performed outside of parens using the / operator, though it can be forced outside of parens with the ./ operator, and ./ is itself deprecated.

The full table of available values is given. always means Less does math eagerly. parens-division is the default described above. parens means parens are required for all math expressions. And strict requires brackets for all operations.

The strictUnits option is the other half. When enabled, less will validate the units used, with the example given being that 4px divided by 2px equals 2, and that 4em divided by 2px throws an error.

Both default to false, which means a stylesheet with a unit mistake in it compiles silently. That is a deliberate choice on the part of LESS, and it is the kind of default that is fine for a design system you control and a problem in a large inherited stylesheet, because turning strictUnits on can turn a working build into a failing one on an unrelated file.

The other options in the same family are more about output than input. compress removes some whitespaces from the output and defaults to false. relativeUrls rewrites URLs to be relative, and false means do not modify URLs. The plugins option, an array, lets you pass LESS plugins into the compiler, which is how the example wires in less-plugin-autoprefix and less-plugin-clean-css.

The example configuration, and what a real build looks like

The usage example in the README is worth reading in full, because it shows a two-target setup that is the normal shape of this task in a real project.

The development target compiles a single file with paths set to assets/css. The production target uses the same paths but adds two plugins, one for vendor prefixing with a browsers list of the last two versions, and one for cleaning the CSS with a cleanCssOptions object, and it also sets modifyVars with an image path pointing at a CDN and a background colour of red.

js
  production: {
    options: {
      paths: ['assets/css'],
      plugins: [
        new (require('less-plugin-autoprefix'))({browsers: ["last 2 versions"]}),
        new (require('less-plugin-clean-css'))(cleanCssOptions)
      ],
      modifyVars: {
        imgPath: '"http://mycdn.com/path/to/images"',
        bgColor: 'red'
      }
    },
    files: {
      'path/to/result.css': 'path/to/source.less'
    }
  }
}

The structure is the standard Grunt one, so a target name becomes a command, grunt less:production. The plugins are required inline with require, which means the plugin packages have to be installed in the project, and in this repository they are dev dependencies, with less-plugin-clean-css listed there.

The repository itself is set up as a Grunt plugin, with a Gruntfile.js, a tasks directory holding the task implementation, a test directory, a docs directory, a CHANGELOG, an AUTHORS file and a LICENSE-MIT. The main entry in package.json is tasks/less.js, and the published files list is just tasks, so the package ships the task and nothing else. The engines field asks for Node 10 or newer.

What the release history says, and the Grunt version caveat

The README's release history is the most informative part for anyone deciding whether to adopt the package now, and it shows a long tail of dependency-bump releases rather than feature work.

The most recent entry is 2021-02-21 for v3.0.0, updated to Less 4 with the ieCompat option removed. The day before, v2.1.0 brought dependency updates and the new process option to modify the written CSS. Before that v2.0.0 in 2018 updated less to ^3.0.0, and v1.4.1 in 2017 fixed sourceMappingURL to be the same as the CSS if not specified and rethrew the compilation error after printing the message.

Two things follow. The headline in the README says v3.0.0 and the package.json version is 3.0.0, while the release list on the services side shows v2.0.0 from 2018-09-08 and v1.4.1 and v1.4.0, which is the difference between a published tag and a published package version, and it means the npm package is ahead of the last tag. And the last push was on 2026-06-23, so the repository is not frozen, but the option surface has been stable since 2021.

There is also a Grunt version caveat stated in the getting started section. This plugin was designed to work with Grunt 0.4.x, and the README says that if you are still using grunt v0.3.x it is strongly recommended that you upgrade, but in case you cannot, use v0.3.2 from a grunt-0.3-stable branch. That sentence is a leftover from a much older era, since the dev dependency is grunt ^1.4.1, and the practical reading is that the plugin works with modern Grunt and the note is historical.

The dependency list is short and tells you what the task does under the hood: less at ^4.1.2 is the compiler, async and lodash handle control flow and data handling, and chalk colours the error output.

Editorial conclusion

grunt-contrib-less fits a project that has already chosen Grunt and LESS and wants the stylesheet step in the same build as the JavaScript, with the compiler options exposed rather than hidden. It does not fit a team that has moved to a modern bundler, since the Grunt task is the tool and the LESS toolchain in general is the older one, and it does not suit a project that wants Sass or PostCSS. Before adding it, check the release history against the LESS major version you depend on, because v3.0.0 updated to Less 4 and removed the ieCompat option, and read the documented defaults for math and strictUnits, since both default to a permissive mode that can hide a mistake in a stylesheet.

Frequently asked questions

How do I install and enable grunt-contrib-less?

Install it with npm install grunt-contrib-less --save-dev, then enable it in your Gruntfile with grunt.loadNpmTasks('grunt-contrib-less'). The task is then run with the grunt less command, and task targets, files and options follow the standard Grunt configuring tasks model.

What LESS options does grunt-contrib-less expose?

It exposes the compiler's own options directly, including paths for scanning @import directives, rootpath, compress, plugins, optimization, strictImports, the math and strictUnits modes, syncImport, dumpLineNumbers, relativeUrls, customFunctions, the sourceMap family of options, modifyVars, banner and process.

How do I override LESS variables for one build target in grunt-contrib-less?

Use the modifyVars option, which overrides global variables and is equivalent to the --modify-vars option in less on the command line. The README's example sets an imgPath pointing at a CDN and a bgColor of red in a production target while the development target leaves them alone.

Which LESS version does the current grunt-contrib-less require?

The package.json depends on less at ^4.1.2, and the release history records that v3.0.0 on 2021-02-21 updated to Less 4 and removed the ieCompat option. The package requires Node 10 or newer and is published under the MIT licence.

Official sources

  1. gruntjs/grunt-contrib-less on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/gruntjs-grunt-contrib-less.svg)](https://hysenlabs.com/projects/gruntjs-grunt-contrib-less)

Was this useful?