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
86 below). 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
179 using 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 { "name" : "foo"
198 , "dependencies" : { "bar" : "0.1.x" }
199 , "scripts": { "start" : "bar ./test" } }
200
201 then you could run npm start to execute the bar script, which is
202 exported into the node_modules/.bin directory on npm install.
203
204 package.json vars
205 The package.json fields are tacked onto the npm_package_ prefix. So,
206 for instance, if you had {"name":"foo", "version":"1.2.5"} in your
207 package.json file, then your package scripts would have the npm_pack‐
208 age_name environment variable set to "foo", and the npm_package_version
209 set to "1.2.5". You can access these variables in your code with
210 process.env.npm_package_name and process.env.npm_package_version, and
211 so on for other fields.
212
213 configuration
214 Configuration parameters are put in the environment with the npm_con‐
215 fig_ prefix. For instance, you can view the effective root config by
216 checking the npm_config_root environment variable.
217
218 Special: package.json config object
219 The package.json "config" keys are overwritten in the environment if
220 there is a config param of <name>[@<version>]:<key>. For example, if
221 the package.json has this:
222
223 { "name" : "foo"
224 , "config" : { "port" : "8080" }
225 , "scripts" : { "start" : "node server.js" } }
226
227 and the server.js is this:
228
229 http.createServer(...).listen(process.env.npm_package_config_port)
230
231 then the user could change the behavior by doing:
232
233 npm config set foo:port 80
234
235 current lifecycle event
236 Lastly, the npm_lifecycle_event environment variable is set to which‐
237 ever stage of the cycle is being executed. So, you could have a single
238 script used for different parts of the process which switches based on
239 what's currently happening.
240
241 Objects are flattened following this format, so if you had
242 {"scripts":{"install":"foo.js"}} in your package.json, then you'd see
243 this in the script:
244
245 process.env.npm_package_scripts_install === "foo.js"
246
247 Examples
248 For example, if your package.json contains this:
249
250 { "scripts" :
251 { "install" : "scripts/install.js"
252 , "postinstall" : "scripts/postinstall.js"
253 , "uninstall" : "scripts/uninstall.js"
254 }
255 }
256
257 then scripts/install.js will be called for the install and post-install
258 stages of the lifecycle, and scripts/uninstall.js will be called when
259 the package is uninstalled. Since scripts/install.js is running for
260 two different phases, it would be wise in this case to look at the
261 npm_lifecycle_event environment variable.
262
263 If you want to run a make command, you can do so. This works just
264 fine:
265
266 { "scripts" :
267 { "preinstall" : "./configure"
268 , "install" : "make && make install"
269 , "test" : "make test"
270 }
271 }
272
273 Exiting
274 Scripts are run by passing the line as a script argument to sh.
275
276 If the script exits with a code other than 0, then this will abort the
277 process.
278
279 Note that these script files don't have to be nodejs or even javascript
280 programs. They just have to be some kind of executable file.
281
282 Hook Scripts
283 If you want to run a specific script at a specific lifecycle event for
284 ALL packages, then you can use a hook script.
285
286 Place an executable file at node_modules/.hooks/{eventname}, and it'll
287 get run for all packages when they are going through that point in the
288 package lifecycle for any packages installed in that root.
289
290 Hook scripts are run exactly the same way as package.json scripts.
291 That is, they are in a separate child process, with the env described
292 above.
293
294 Best Practices
295 · Don't exit with a non-zero error code unless you really mean it.
296 Except for uninstall scripts, this will cause the npm action to fail,
297 and potentially be rolled back. If the failure is minor or only will
298 prevent some optional features, then it's better to just print a
299 warning and exit successfully.
300
301 · Try not to use scripts to do what npm can do for you. Read through
302 npm help package.json to see all the things that you can specify and
303 enable by simply describing your package appropriately. In general,
304 this will lead to a more robust and consistent state.
305
306 · Inspect the env to determine where to put things. For instance, if
307 the npm_config_binroot environment variable is set to /home/user/bin,
308 then don't try to install executables into /usr/local/bin. The user
309 probably set it up that way for a reason.
310
311 · Don't prefix your script commands with "sudo". If root permissions
312 are required for some reason, then it'll fail with that error, and
313 the user will sudo the npm command in question.
314
315 · Don't use install. Use a .gyp file for compilation, and prepublish
316 for anything else. You should almost never have to explicitly set a
317 preinstall or install script. If you are doing this, please consider
318 if there is another option. The only valid use of install or prein‐
319 stall scripts is for compilation which must be done on the target
320 architecture.
321
322
323 See Also
324 · npm help run-script
325
326 · npm help package.json
327
328 · npm help developers
329
330 · npm help install
331
332
333
334
335 March 2020 SCRIPTS(7)