NPM Scripts as a Build Tool
Tags: productivity, tutorial, npm, beginners
Published: 2019-06-10 15:02:55

---
title: NPM Scripts as a Build Tool
published: true
tags: productivity, tutorial, npm, beginners
cover_image: https://thepracticaldev.s3.amazonaws.com/i/cf5tafh6jnwa4gmvn2cx.png
canonical_url: https://nervewax.com/npm-scripts-compiler/
---

Build tools are great for helping devs save time by automating tasks. In this post, I’ll explain how I’m using npm scripts as a build tool, by directly running packages, rather than going via something like Grunt, Gulp, Webpack, Parcel etc.

For those already familiar with the tools mentioned above, I hope this offers a simpler alternative. Those who’ve not used build tools before, this could be an easy entry point, since a lot can be achieved with even just a basic understanding.

## What’s npm?

[Node Package Manager](https://www.npmjs.com/) is a software registry, that many developers use to download their favourite packages and tools, usually via the [npm Command Line Interface](https://docs.npmjs.com/cli/npm).

To use npm, [install Node.js](https://nodejs.org/) on your machine, then you’ll have access to the npm cli in your shell by typing `npm`.

Also, see [“Downloading and installing Node.js and npm”](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm).

## Scripts example

Once you have npm on your machine, add a `package.json` file to your project root or run `npm init`. This file contains info about your project, packages you’ve added and any scripts defined, amongst other things. A basic package.json will look something like this:

```json
{
  "name": "test-project",
  "version": "1.0.0",
  "scripts": {
    "test": "echo \"Test works!\""
  }
}

```

Under “scripts” is where all our npm scripts are defined. Running `npm test` inside the directory with this package.json will return `Test works!` in the shell, try it for yourself!

## npm as a build tool

Using npm scripts, we can put together more complex tasks, similar to the ones you might find in other build tools. Then, with the help of some utility packages, we can have the tasks run in sequence or parallel and trigger when changes are made to specific files.

Over on GitHub, I’ve created a repo with my own [package.json](https://github.com/nervewax/npm-compiler/blob/master/package.json) that contains scripts which form a basic build process.

In this file, I’ve added tasks like `build`, `clean` and `watch`, which run other subtasks grouped via their keyword. For example `watch:*` refers to all tasks starting with `watch:`. Using these tasks, this tool accomplishes the following:

- Compiles sass files into CSS files.
- Minifies CSS and JS files.
- Compresses images and SVG files, ready for a live site.
- Runs the above tasks after saving changes and refreshes the browser.

**[github.com/nervewax/npm-compiler](https://github.com/nervewax/npm-compiler)**

If you want to get started with npm scripts yourself, try downloading the repo and running some of the tasks included. Once you’re more familiar with those, you can assemble your own build process to fit your needs.

Below I’ve made a list of the packages found in my repo and what they do. Each of these packages has its own instructions, found in the readme of the corresponding linked npm page.

### Utilities

[mkdirp](https://www.npmjs.com/package/mkdirp) - makes a directory and any sub-directories, which is useful for when you need to create folder structures.

[onchange](https://www.npmjs.com/package/onchange) - watches files and then runs a task when anything is added, changed or deleted.

[npm-run-all](https://www.npmjs.com/package/npm-run-all) - lets you run multiple tasks in sequence or parallel to each other.

[rimraf](https://www.npmjs.com/package/rimraf) - runs the remove command recursively, including read only files.

[livereload](https://www.npmjs.com/package/livereload) - refreshes your browser when it detects changes.

### CSS

[node-sass](https://www.npmjs.com/package/node-sass) - compiles scss files into css.

[postcss-cli](https://www.npmjs.com/package/postcss-cli) - After running the above, [PostCSS](https://github.com/postcss/postcss) can then be used to run a few more tasks, they are the following:

[autoprefixer](https://www.npmjs.com/package/autoprefixer) - automatically adds vendor prefixes to any styles that need them, in order to work in different browsers. Such as the `-webkit-` or `-ms-` prefixes.

[pixrem](https://www.npmjs.com/package/pixrem) - provides a `px` fallback for `rem` units.

[cssnano](https://www.npmjs.com/package/cssnano) - compresses css files.

### JS

[terser](https://www.npmjs.com/package/terser) - compresses js files.

[rollup](https://www.npmjs.com/package/rollup) - is not actually included in my repo! But it’s an alternative to dealing with js that also handles es6 modules, so I’ll certainly be looking into using this myself.

### Other stuff

[html-minifier](https://www.npmjs.com/package/html-minifier) - compresses HTML files.

[imagemin-cli](https://www.npmjs.com/package/imagemin-cli) - reduces image file size. Although this can be time consuming, so this is a candidate for removal.

[svgo](https://www.npmjs.com/package/svgo) - optimises and reduces the file size of SVGs.

## That's all folks

Hopefully, if you’ve read this, you’ll have a little more insight into what npm scripts can do. Maybe this has also convinced you to switch over from one of the more complex build tools?

Either way, thanks for reading, if you have any questions, I’d be happy to help if I can. 👋

### Further reading

[What’s a build tool?](https://stackoverflow.com/questions/7249871/what-is-a-build-tool)
[css-tricks.com/why-npm-scripts](https://css-tricks.com/why-npm-scripts/)
[gablaxian.com/blog/using-npm-as-a-build-too](https://gablaxian.com/blog/using-npm-as-a-build-tool)
[keithcirkel.co.uk/how-to-use-npm-as-a-build-tool](https://www.keithcirkel.co.uk/how-to-use-npm-as-a-build-tool/)