title: npm install if package.json was modified
body: <p>TL;DR: Is there a way to have <code>npm install</code> run automatically before running any npm script if your <code>package.json</code> has been modified?</p>
  
  <h2>Problem Scenario</h2>
  
  <p>You pull or checkout a branch that updated <code>package.json</code>. You run <code>npm run my-script</code>. <code>my-script</code> depends on a package that has newly been added to <code>package.json</code>. <code>my-script</code> fails. You wonder why. Before flipping over your desk you run <code>npm install</code> just to be sure. <code>my-script</code> runs successfully. You don't need a new desk.</p>
  
  <p>I know that build / task runner tools like <code>gradle</code> make sure that your dependencies are up-to-date before running a task. I has always been a (minor) pain point that <code>npm</code> doesn't do it. I stumbled over two solutions that I don't particluarly like.</p>
  
  <h2>Non-Ideal Solution: make</h2>
  
  <p>Instead of relying on npm scripts in your <code>package.json</code> to run commands you use <code>make</code> and make use of its integrated dependency tracking with the following trick:</p>
  
  <pre><code># Smart install: Only executes if package.json's
  # modification date is later than node_module's
  
  node_modules: package.json
      npm install
      @rm -f node_modules/.modified
      @touch -m node_modules/.modified
  
  install: node_modules 
  </code></pre>
  
  <p>Source: <a href="https://mattandre.ws/2016/05/make-for-hipsters/" rel="noreferrer">https://mattandre.ws/2016/05/make-for-hipsters/</a></p>
  
  <p>The problem is that you know have to rely on <code>make</code> to run scripts and lose certain advantages of npm scripts such as conveniently referring to other scripts and running scripts in parallel (<code>npm-run-all</code>). It's also harder to work with others if they don't know <code>make</code> or have problems running it (Windows). It's an archaic tool outside of the node/npm ecosystem and too costly just for this smart install advantage.</p>
  
  <h2>Non-Ideal Solution: Git hook</h2>
  
  <p>Another way is to add a <code>post-merge</code> git hook.</p>
  
  <p>The problem is that this solution is local to the repository and can't be easily shared. <code>npm install</code> will only be run automatically on git merges. When you change <code>package.json</code> in any other way you still have to remember running <code>npm install</code>. Admittedly, that's a minor point in practice. Nonetheless, it would be nice to never have to think about running <code>npm install</code> at all when you want to run a script.</p>
  
  <p>Source: <a href="https://davidwalsh.name/git-hook-npm-install-package-json-modified" rel="noreferrer">https://davidwalsh.name/git-hook-npm-install-package-json-modified</a></p>
  
  <h2>Ideal Solution</h2>
  
  <p>I'd like to define my <code>package.json</code> in a way similar to:</p>
  
  <pre><code>{
    "scripts": {
      "pre-run": "npm-smart-install",
      "my-script": "…"
    },
    "dependencies": {
      "npm-smart-install": "1.0.0"
    }
  }
  </code></pre>
  
  <p><code>npm-smart-install</code> is a hypothetical npm package that I wish existed. <code>pre-run</code> is a hypothetical npm-scripts lifecycle hook. When I run <code>npm run my-script</code> and <code>package.json</code> has been modified since the last run of any script, run <code>npm install</code> before running <code>my-script</code>.</p>
  
  <p>To repeat: Is there a way to have <code>npm install</code> run automatically before running any npm script if your <code>package.json</code> has been modified without relying on tools outside the npm ecosystem?</p>