npm-scripts > grunt


"scripts": {
  "watch-css": "onchange 'style/*.less' -- npm run build-css",
  "watch-js": "watchify -t [ babelify --presets [ es2015 react ] ] js/*.jsx js/*.js -o dist/bundle.js -dv",
  "watch": "npm run watch-css & npm run watch-js",
  "build-css": "lessc --autoprefix='last 2 versions' style/main.less dist/style.css",
  "build-js": "browserify -t [ babelify --presets [ es2015 react ] ] js/*.jsx js/*.js -o dist/bundle.js",
  "build": "npm run build-css && npm run build-js"

Reasons: simpler, less stuff to install, fewer files in your root, simpler, no plugins, same functionality, simpler.

Not only do you not need to install/maintain/update grunt, you don't need any of the grunt plugins. Instead of installing and updating grunt-browserify, grunt-less, etc, you just install the actual browserify package. You've just cut your dependencies in half.

Above is an example of what I use for a project with React, ES2015, and Less. I use browserify with a babelify transform to package my js + jsx modules, and watchify to do the same on file changes. I use less to compile css from my main.less file, from which I import all other less files. onchange enables us to watch for changes in your less files. You can then run npm run build to build your css/js, and npm run watch to recompile on changes during development.

npm-scripts has lots of nice built in scripts and pre and post hooks that you can take advantage of. Bottom line, it's better to take advantage of your already existing package.json than add an entire new dependency to your project.