# Run package.json scripts upon any file changes in a folder

> Learn how to re-run a package.json script automatically whenever a file in a folder changes, using the watch npm package to rebuild on every save.

Author: [Flavio Copes](https://flaviocopes.com/about/) | Published: 2018-07-01 | Updated: 2026-08-07 | Topics: [Node.js](https://flaviocopes.com/tags/node/) | Canonical: https://flaviocopes.com/package-json-watch/

To run a `package.json` script whenever a file changes in a folder, we can use the [`watch`](https://www.npmjs.com/package/watch) [npm](https://flaviocopes.com/npm/) package. It watches a folder tree and runs a command of our choice on every change.

My practical problem: I want to automatically regenerate the CSS, going through a PostCSS pipeline, upon file changes.

The approach I describe will work for any kind of automatic file and folder watching, not just for this specific case.

I have this script in action, which I run using `yarn build:css`:

```json
"scripts": {
  "build:css": "postcss src/tailwind.css -o static/dist/tailwind.css"
}
```

and I want to re-run it whenever something changes in the `layouts` folder, which contains all the HTML files that build up my site.

If you're familiar with Tailwind, it creates a slightly big CSS file with all the things you might need, and you can optimize it by removing any class you don't use.

Every time I change something in there, I want to regenerate the CSS, and trigger the purge and minification I set up in the [PostCSS](https://flaviocopes.com/postcss/) setup.

How to do this?

Install the `watch` package:

```bash
npm install watch
```

and add the `watch` script to your `package.json` file. You already had `build:css` from before, we just add a script that watches the layouts folder and runs `build:css` upon every change:

```json
"scripts": {
  "build:css": "postcss src/tailwind.css -o static/dist/tailwind.css",
  "watch": "watch 'npm run build:css' ./layouts"
}
```

Now run `npm run watch` or `yarn watch`. Save any file inside `layouts`, and the CSS is rebuilt.

## How the command works

The syntax is `watch '<command>' <folder>`. The folder is watched recursively, so files in subfolders trigger the command too.

You can also watch more than one folder, by listing them all:

```json
"watch": "watch 'npm run build:css' ./layouts ./content"
```

## Watch out for the quotes

The command must be wrapped in quotes. Since the script already lives inside a JSON string delimited by double quotes, use single quotes around the command.

Without them, the shell splits `npm run build:css` into separate arguments, and `watch` treats `run` and `build:css` as folders to watch. You get errors about folders that don't exist, or a watcher that does nothing useful.

## Too many rebuilds?

Some editors save a file multiple times in a row, and each save triggers the command. If your build is slow, that piles up.

The `--wait` flag helps. It disables watching for a number of seconds after each run:

```json
"watch": "watch 'npm run build:css' ./layouts --wait=3"
```

With this, after a rebuild the watcher waits 3 seconds before it can fire again, so a burst of saves results in one rebuild instead of five.
