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