1SCRIPTS(7) SCRIPTS(7)
2
3
4
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
38 • prepare, 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
150 • prepare
151
152
153 npm help ci
154 • preinstall
155
156 • install
157
158 • postinstall
159
160 • prepublish
161
162 • preprepare
163
164 • prepare
165
166 • postprepare
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
173 • prepare
174
175
176 npm help install
177 These also run when you run npm install -g <pkg-name>
178
179 • preinstall
180
181 • install
182
183 • postinstall
184
185 • prepublish
186
187 • preprepare
188
189 • prepare
190
191 • postprepare
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
202 • prepack
203
204 • prepare
205
206 • postpack
207
208
209 npm help publish
210 • prepublishOnly
211
212 • prepack
213
214 • prepare
215
216 • postpack
217
218 • publish
219
220 • postpublish
221
222
223 npm help rebuild
224 • preinstall
225
226 • install
227
228 • postinstall
229
230 • prepare
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
241 • prerestart
242
243 • restart
244
245 • postrestart
246
247
248 npm run <user defined> ⟨/commands/npm-run-script⟩
249 • pre<user-defined>
250
251 • <user-defined>
252
253 • post<user-defined>
254
255
256 npm help start
257 • prestart
258
259 • start
260
261 • poststart
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
269 • prestop
270
271 • stop
272
273 • poststop
274
275
276 npm help test
277 • pretest
278
279 • test
280
281 • posttest
282
283
284 npm help version
285 • preversion
286
287 • version
288
289 • postversion
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
441 • package.json ⟨/configuring-npm/package-json⟩
442
443 • npm help developers
444
445 • npm help install
446
447
448
449 November 2023 SCRIPTS(7)