1SCRIPTS(7) SCRIPTS(7)
2
3
4
6 scripts - How npm handles the "scripts" field
7
8 Description
9 The "scripts" property of of your package.json file supports a number
10 of 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 Life Cycle Scripts
31 There are some special life cycle scripts that happen only in certain
32 situations. These scripts happen in addtion to the "pre" and "post"
33 script.
34
35 • prepare, prepublish, prepublishOnly, prepack, postpack
36
37
38 prepare (since npm@4.0.0)
39
40 • Runs BEFORE the package is packed
41
42 • Runs BEFORE the package is published
43
44 • Runs on local npm install without any arguments
45
46 • Run AFTER prepublish, but BEFORE prepublishOnly
47
48 • NOTE: If a package being installed through git contains a prepare
49 script, its dependencies and devDependencies will be installed, and
50 the prepare script will be run, before the package is packaged and
51 installed.
52
53
54 prepublish (DEPRECATED)
55
56 • Same as prepare
57
58
59 prepublishOnly
60
61 • Runs BEFORE the package is prepared and packed, ONLY on npm publish.
62
63
64 prepack
65
66 • Runs BEFORE a tarball is packed (on "npm pack", "npm publish", and
67 when installing a git dependencies).
68
69 • NOTE: "npm run pack" is NOT the same as "npm pack". "npm run pack" is
70 an arbitrary user defined script name, where as, "npm pack" is a CLI
71 defined command.
72
73
74 postpack
75
76 • Runs AFTER the tarball has been generated and moved to its final des‐
77 tination.
78
79
80 Prepare and Prepublish
81 Deprecation Note: prepublish
82
83 Since npm@1.1.71, the npm CLI has run the prepublish script for both
84 npm publish and npm install, because it's a convenient way to prepare a
85 package for use (some common use cases are described in the section be‐
86 low). It has also turned out to be, in practice, very confusing
87 https://github.com/npm/npm/issues/10074. As of npm@4.0.0, a new event
88 has been introduced, prepare, that preserves this existing behavior. A
89 new event, prepublishOnly has been added as a transitional strategy to
90 allow users to avoid the confusing behavior of existing npm versions
91 and only run on npm publish (for instance, running the tests one last
92 time to ensure they're in good shape).
93
94 See https://github.com/npm/npm/issues/10074 for a much lengthier justi‐
95 fication, with further reading, for this change.
96
97 Use Cases
98
99 If you need to perform operations on your package before it is used, in
100 a way that is not dependent on the operating system or architecture of
101 the target system, use a prepublish script. This includes tasks such
102 as:
103
104 • Compiling CoffeeScript source code into JavaScript.
105
106 • Creating minified versions of JavaScript source code.
107
108 • Fetching remote resources that your package will use.
109
110
111 The advantage of doing these things at prepublish time is that they can
112 be done once, in a single place, thus reducing complexity and variabil‐
113 ity. Additionally, this means that:
114
115 • You can depend on coffee-script as a devDependency, and thus your
116 users don't need to have it installed.
117
118 • You don't need to include minifiers in your package, reducing the
119 size for your users.
120
121 • You don't need to rely on your users having curl or wget or other
122 system tools on the target machines.
123
124
125 Life Cycle Operation Order
126 npm help publish
127 • prepublishOnly
128
129 • prepare
130
131 • prepublish
132
133 • publish
134
135 • postpublish
136
137
138 npm help pack
139 • prepack
140
141 • postpack
142
143
144 npm help install
145 • preinstall
146
147 • install
148
149 • postinstall
150
151
152 Also triggers
153
154 • prepublish (when on local)
155
156 • prepare (when on local)
157
158
159 npm help start
160 npm run start has an npm start shorthand.
161
162 • prestart
163
164 • start
165
166 • poststart
167
168
169 Default Values
170 npm will default some script values based on package contents.
171
172 • "start": "node server.js": If there is a server.js file in the root
173 of your package, then npm will default the start command to node
174 server.js.
175
176 • "install": "node-gyp rebuild": If there is a binding.gyp file in the
177 root of your package and you haven't defined your own install or pre‐
178 install scripts, npm will default the install command to compile us‐
179 ing node-gyp.
180
181
182 User
183 If npm was invoked with root privileges, then it will change the uid to
184 the user account or uid specified by the user config, which defaults to
185 nobody. Set the unsafe-perm flag to run scripts with root privileges.
186
187 Environment
188 Package scripts run in an environment where many pieces of information
189 are made available regarding the setup of npm and the current state of
190 the process.
191
192 path
193 If you depend on modules that define executable scripts, like test
194 suites, then those executables will be added to the PATH for executing
195 the scripts. So, if your package.json has this:
196
197 {
198 "name" : "foo",
199 "dependencies" : {
200 "bar" : "0.1.x"
201 },
202 "scripts": {
203 "start" : "bar ./test"
204 }
205 }
206
207 then you could run npm start to execute the bar script, which is ex‐
208 ported into the node_modules/.bin directory on npm install.
209
210 package.json vars
211 The package.json fields are tacked onto the npm_package_ prefix. So,
212 for instance, if you had {"name":"foo", "version":"1.2.5"} in your
213 package.json file, then your package scripts would have the npm_pack‐
214 age_name environment variable set to "foo", and the npm_package_version
215 set to "1.2.5". You can access these variables in your code with
216 process.env.npm_package_name and process.env.npm_package_version, and
217 so on for other fields.
218
219 configuration
220 Configuration parameters are put in the environment with the npm_con‐
221 fig_ prefix. For instance, you can view the effective root config by
222 checking the npm_config_root environment variable.
223
224 Special: package.json config object
225 The package.json "config" keys are overwritten in the environment if
226 there is a config param of <name>[@<version>]:<key>. For example, if
227 the package.json has this:
228
229 {
230 "name" : "foo",
231 "config" : {
232 "port" : "8080"
233 },
234 "scripts" : {
235 "start" : "node server.js"
236 }
237 }
238
239 and the server.js is this:
240
241 http.createServer(...).listen(process.env.npm_package_config_port)
242
243 then the user could change the behavior by doing:
244
245 npm config set foo:port 80
246
247 current lifecycle event
248 Lastly, the npm_lifecycle_event environment variable is set to which‐
249 ever stage of the cycle is being executed. So, you could have a single
250 script used for different parts of the process which switches based on
251 what's currently happening.
252
253 Objects are flattened following this format, so if you had
254 {"scripts":{"install":"foo.js"}} in your package.json, then you'd see
255 this in the script:
256
257 process.env.npm_package_scripts_install === "foo.js"
258
259 Examples
260 For example, if your package.json contains this:
261
262 {
263 "scripts" : {
264 "install" : "scripts/install.js",
265 "postinstall" : "scripts/install.js",
266 "uninstall" : "scripts/uninstall.js"
267 }
268 }
269
270 then scripts/install.js will be called for the install and post-install
271 stages of the lifecycle, and scripts/uninstall.js will be called when
272 the package is uninstalled. Since scripts/install.js is running for
273 two different phases, it would be wise in this case to look at the
274 npm_lifecycle_event environment variable.
275
276 If you want to run a make command, you can do so. This works just
277 fine:
278
279 {
280 "scripts" : {
281 "preinstall" : "./configure",
282 "install" : "make && make install",
283 "test" : "make test"
284 }
285 }
286
287 Exiting
288 Scripts are run by passing the line as a script argument to sh.
289
290 If the script exits with a code other than 0, then this will abort the
291 process.
292
293 Note that these script files don't have to be nodejs or even javascript
294 programs. They just have to be some kind of executable file.
295
296 Hook Scripts
297 If you want to run a specific script at a specific lifecycle event for
298 ALL packages, then you can use a hook script.
299
300 Place an executable file at node_modules/.hooks/{eventname}, and it'll
301 get run for all packages when they are going through that point in the
302 package lifecycle for any packages installed in that root.
303
304 Hook scripts are run exactly the same way as package.json scripts.
305 That is, they are in a separate child process, with the env described
306 above.
307
308 Best Practices
309 • Don't exit with a non-zero error code unless you really mean it. Ex‐
310 cept for uninstall scripts, this will cause the npm action to fail,
311 and potentially be rolled back. If the failure is minor or only will
312 prevent some optional features, then it's better to just print a
313 warning and exit successfully.
314
315 • Try not to use scripts to do what npm can do for you. Read through
316 npm help package.json to see all the things that you can specify and
317 enable by simply describing your package appropriately. In general,
318 this will lead to a more robust and consistent state.
319
320 • Inspect the env to determine where to put things. For instance, if
321 the npm_config_binroot environment variable is set to /home/user/bin,
322 then don't try to install executables into /usr/local/bin. The user
323 probably set it up that way for a reason.
324
325 • Don't prefix your script commands with "sudo". If root permissions
326 are required for some reason, then it'll fail with that error, and
327 the user will sudo the npm command in question.
328
329 • Don't use install. Use a .gyp file for compilation, and prepublish
330 for anything else. You should almost never have to explicitly set a
331 preinstall or install script. If you are doing this, please consider
332 if there is another option. The only valid use of install or prein‐
333 stall scripts is for compilation which must be done on the target ar‐
334 chitecture.
335
336
337 See Also
338 • npm help run-script
339
340 • npm help package.json
341
342 • npm help developers
343
344 • npm help install
345
346
347
348
349 April 2021 SCRIPTS(7)