1SCRIPTS(7)                                                          SCRIPTS(7)
2
3
4

NAME

6       scripts - How npm handles the "scripts" field
7
8   Description
9       The  "scripts"  property of your package.json file supports a number of
10       built-in scripts and their preset life cycle events as  well  as  arbi‐
11       trary  scripts.  These  all  can  be executed by running npm run-script
12       <stage> or npm run <stage> for short. Pre and post commands with match‐
13       ing  names  will  be run for those as well (e.g. premyscript, myscript,
14       postmyscript). Scripts from dependencies can be run  with  npm  explore
15       <pkg> -- npm run <stage>.
16
17   Pre & Post Scripts
18       To  create  "pre"  or  "post"  scripts  for  any scripts defined in the
19       "scripts" section of the package.json,  simply  create  another  script
20       with a matching name and add "pre" or "post" to the beginning of them.
21
22         {
23           "scripts": {
24             "precompress": "{{ executes BEFORE the `compress` script }}",
25             "compress": "{{ run command to compress files }}",
26             "postcompress": "{{ executes AFTER `compress` script }}"
27           }
28         }
29
30       In  this  example  npm  run compress would execute these scripts as de‐
31       scribed.
32
33   Life Cycle Scripts
34       There are some special life cycle scripts that happen only  in  certain
35       situations.  These  scripts  happen  in  addition  to  the  pre<event>,
36       post<event>, and <event> scripts.
37
38prepare, prepublish, prepublishOnly, prepack,  postpack,  dependen‐
39           cies
40
41
42       prepare (since npm@4.0.0)
43
44       •   Runs  BEFORE the package is packed, i.e. during npm publish and npm
45           pack
46
47       •   Runs on local npm install without any arguments
48
49       •   Runs AFTER prepublish, but BEFORE prepublishOnly
50
51       •   NOTE: If a package being installed through git contains  a  prepare
52           script, its dependencies and devDependencies will be installed, and
53           the prepare script will be run, before the package is packaged  and
54           installed.
55
56       •   As of npm@7 these scripts run in the background. To see the output,
57           run with: --foreground-scripts.
58
59
60       prepublish (DEPRECATED)
61
62       •   Does not run during npm publish, but does run during npm ci and npm
63           install. See below for more info.
64
65
66       prepublishOnly
67
68       •   Runs  BEFORE  the  package is prepared and packed, ONLY on npm pub‐
69           lish.
70
71
72       prepack
73
74       •   Runs BEFORE a tarball is packed (on "npm pack", "npm publish",  and
75           when installing a git dependency).
76
77       •   NOTE:  "npm run pack" is NOT the same as "npm pack". "npm run pack"
78           is an arbitrary user defined script name, where as, "npm pack" is a
79           CLI defined command.
80
81
82       postpack
83
84       •   Runs AFTER the tarball has been generated but before it is moved to
85           its final destination (if at all, publish does not save the tarball
86           locally)
87
88
89       dependencies
90
91       •   Runs AFTER any operations that modify the node_modules directory IF
92           changes occurred.
93
94       •   Does NOT run in global mode
95
96
97   Prepare and Prepublish
98       Deprecation Note: prepublish
99
100       Since npm@1.1.71, the npm CLI has run the prepublish  script  for  both
101       npm publish and npm install, because it's a convenient way to prepare a
102       package for use (some common use cases are described in the section be‐
103       low).  It  has  also  turned  out  to  be,  in practice, very confusing
104       https://github.com/npm/npm/issues/10074. As of npm@4.0.0, a new event
105       has  been introduced, prepare, that preserves this existing behavior. A
106       new event, prepublishOnly has been added as a transitional strategy  to
107       allow  users  to  avoid the confusing behavior of existing npm versions
108       and only run on npm publish (for instance, running the tests  one  last
109       time to ensure they're in good shape).
110
111       See https://github.com/npm/npm/issues/10074 for a much lengthier jus‐
112       tification, with further reading, for this change.
113
114       Use Cases
115
116       If you need to perform operations on your package before it is used, in
117       a  way that is not dependent on the operating system or architecture of
118       the target system, use a prepublish script. This  includes  tasks  such
119       as:
120
121       •   Compiling CoffeeScript source code into JavaScript.
122
123       •   Creating minified versions of JavaScript source code.
124
125       •   Fetching remote resources that your package will use.
126
127
128       The advantage of doing these things at prepublish time is that they can
129       be done once, in a single place, thus reducing complexity and variabil‐
130       ity. Additionally, this means that:
131
132       •   You  can  depend on coffee-script as a devDependency, and thus your
133           users don't need to have it installed.
134
135       •   You don't need to include minifiers in your package,  reducing  the
136           size for your users.
137
138       •   You  don't  need to rely on your users having curl or wget or other
139           system tools on the target machines.
140
141
142   Dependencies
143       The dependencies script is run any time an npm command  causes  changes
144       to  the  node_modules  directory. It is run AFTER the changes have been
145       applied and the package.json and package-lock.json files have been  up‐
146       dated.
147
148   Life Cycle Operation Order
149   npm help
150prepare
151
152
153   npm help ci
154preinstall
155
156install
157
158postinstall
159
160prepublish
161
162preprepare
163
164prepare
165
166postprepare
167
168
169       These  all  run after the actual installation of modules into node_mod‐
170       ules, in order, with no internal actions happening in between
171
172   npm help diff
173prepare
174
175
176   npm help install
177       These also run when you run npm install -g <pkg-name>
178
179preinstall
180
181install
182
183postinstall
184
185prepublish
186
187preprepare
188
189prepare
190
191postprepare
192
193
194       If there is a binding.gyp file in the root  of  your  package  and  you
195       haven't  defined  your  own install or preinstall scripts, npm will de‐
196       fault the install command to compile using node-gyp  via  node-gyp  re‐
197       build
198
199       These are run from the scripts of <pkg-name>
200
201   npm help pack
202prepack
203
204prepare
205
206postpack
207
208
209   npm help publish
210prepublishOnly
211
212prepack
213
214prepare
215
216postpack
217
218publish
219
220postpublish
221
222
223   npm help rebuild
224preinstall
225
226install
227
228postinstall
229
230prepare
231
232
233       prepare  is  only  run if the current directory is a symlink (e.g. with
234       linked packages)
235
236   npm help restart
237       If there is a restart script defined, these events are  run,  otherwise
238       stop  and  start  are both run if present, including their pre and post
239       iterations)
240
241prerestart
242
243restart
244
245postrestart
246
247
248   npm run <user defined> ⟨/commands/npm-run-script⟩
249pre<user-defined>
250
251<user-defined>
252
253post<user-defined>
254
255
256   npm help start
257prestart
258
259start
260
261poststart
262
263
264       If there is a server.js file in the root of your package, then npm will
265       default  the  start  command  to node server.js. prestart and poststart
266       will still run in this case.
267
268   npm help stop
269prestop
270
271stop
272
273poststop
274
275
276   npm help test
277pretest
278
279test
280
281posttest
282
283
284   npm help version
285preversion
286
287version
288
289postversion
290
291
292   A Note on a lack of npm help uninstall scripts
293       While npm v6 had uninstall lifecycle scripts, npm v7 does not.  Removal
294       of  a  package can happen for a wide variety of reasons, and there's no
295       clear way to currently give the script enough context to be useful.
296
297       Reasons for a package removal include:
298
299       •   a user directly uninstalled this package
300
301       •   a user uninstalled a dependant package and so  this  dependency  is
302           being uninstalled
303
304       •   a user uninstalled a dependant package but another package also de‐
305           pends on this version
306
307       •   this version has been merged as a duplicate with another version
308
309       •   etc.
310
311
312       Due to the lack of necessary context, uninstall lifecycle  scripts  are
313       not implemented and will not function.
314
315   User
316       When  npm is run as root, scripts are always run with the effective uid
317       and gid of the working directory owner.
318
319   Environment
320       Package scripts run in an environment where many pieces of  information
321       are  made available regarding the setup of npm and the current state of
322       the process.
323
324   path
325       If you depend on modules that  define  executable  scripts,  like  test
326       suites,  then those executables will be added to the PATH for executing
327       the scripts. So, if your package.json has this:
328
329         {
330           "name" : "foo",
331           "dependencies" : {
332             "bar" : "0.1.x"
333           },
334           "scripts": {
335             "start" : "bar ./test"
336           }
337         }
338
339       then you could run npm start to execute the bar script,  which  is  ex‐
340       ported into the node_modules/.bin directory on npm install.
341
342   package.json vars
343       The  package.json  fields  are tacked onto the npm_package_ prefix. So,
344       for instance, if you  had  {"name":"foo",  "version":"1.2.5"}  in  your
345       package.json  file,  then your package scripts would have the npm_pack‐
346       age_name environment variable set to "foo", and the npm_package_version
347       set  to  "1.2.5".  You  can  access  these  variables in your code with
348       process.env.npm_package_name and  process.env.npm_package_version,  and
349       so on for other fields.
350
351       See  package.json  ⟨/configuring-npm/package-json⟩  for more on package
352       configs.
353
354   current lifecycle event
355       Lastly, the npm_lifecycle_event environment variable is set  to  which‐
356       ever  stage of the cycle is being executed. So, you could have a single
357       script used for different parts of the process which switches based  on
358       what's currently happening.
359
360       Objects   are   flattened   following   this  format,  so  if  you  had
361       {"scripts":{"install":"foo.js"}} in your package.json, then  you'd  see
362       this in the script:
363
364         process.env.npm_package_scripts_install === "foo.js"
365
366   Examples
367       For example, if your package.json contains this:
368
369         {
370           "scripts" : {
371             "install" : "scripts/install.js",
372             "postinstall" : "scripts/install.js",
373             "uninstall" : "scripts/uninstall.js"
374           }
375         }
376
377       then scripts/install.js will be called for the install and post-install
378       stages of the lifecycle, and scripts/uninstall.js will be  called  when
379       the package is uninstalled. Since scripts/install.js is running for two
380       different phases, it would  be  wise  in  this  case  to  look  at  the
381       npm_lifecycle_event environment variable.
382
383       If you want to run a make command, you can do so. This works just fine:
384
385         {
386           "scripts" : {
387             "preinstall" : "./configure",
388             "install" : "make && make install",
389             "test" : "make test"
390           }
391         }
392
393   Exiting
394       Scripts are run by passing the line as a script argument to sh.
395
396       If  the script exits with a code other than 0, then this will abort the
397       process.
398
399       Note that these script files don't have to be  Node.js  or  even  Java‐
400       Script programs. They just have to be some kind of executable file.
401
402   Best Practices
403       •   Don't  exit  with  a non-zero error code unless you really mean it.
404           Except for uninstall scripts, this will cause  the  npm  action  to
405           fail,  and  potentially  be rolled back. If the failure is minor or
406           only will prevent some optional features, then it's better to  just
407           print a warning and exit successfully.
408
409       •   Try  not to use scripts to do what npm can do for you. Read through
410           package.json ⟨/configuring-npm/package-json⟩ to see all the  things
411           that  you  can specify and enable by simply describing your package
412           appropriately. In general, this will lead to a more robust and con‐
413           sistent state.
414
415       •   Inspect  the env to determine where to put things. For instance, if
416           the   npm_config_binroot   environment   variable   is    set    to
417           /home/user/bin, then don't try to install executables into /usr/lo‐
418           cal/bin. The user probably set it up that way for a reason.
419
420       •   Don't prefix your script commands with "sudo". If root  permissions
421           are  required for some reason, then it'll fail with that error, and
422           the user will sudo the npm command in question.
423
424       •   Don't use install. Use a .gyp file for compilation, and prepare for
425           anything  else.  You  should  almost never have to explicitly set a
426           preinstall or install script. If you are doing  this,  please  con‐
427           sider  if there is another option. The only valid use of install or
428           preinstall scripts is for compilation which must  be  done  on  the
429           target architecture.
430
431       •   Scripts  are run from the root of the package folder, regardless of
432           what the current working directory is when npm is invoked.  If  you
433           want  your script to use different behavior based on what subdirec‐
434           tory you're in, you can  use  the  INIT_CWD  environment  variable,
435           which holds the full path you were in when you ran npm run.
436
437
438   See Also
439       •   npm help run-script
440
441package.json ⟨/configuring-npm/package-json⟩
442
443       •   npm help developers
444
445       •   npm help install
446
447
448
449                                 November 2023                      SCRIPTS(7)
Impressum