UNPKG

26.8 kBMarkdownView Raw
1# browserify
2
3`require('modules')` in the browser
4
5Use a [node](http://nodejs.org)-style `require()` to organize your browser code
6and load modules installed by [npm](https://www.npmjs.com).
7
8browserify will recursively analyze all the `require()` calls in your app in
9order to build a bundle you can serve up to the browser in a single `<script>`
10tag.
11
12[![build status](https://img.shields.io/travis/browserify/browserify/master.svg)](https://travis-ci.org/browserify/browserify)
13
14![browserify!](./assets/logo.png)
15
16# getting started
17
18If you're new to browserify, check out the
19[browserify handbook](https://github.com/browserify/browserify-handbook)
20and the resources on [browserify.org](http://browserify.org/).
21
22# example
23
24Whip up a file, `main.js` with some `require()`s in it. You can use relative
25paths like `'./foo.js'` and `'../lib/bar.js'` or module paths like `'gamma'`
26that will search `node_modules/` using
27[node's module lookup algorithm](https://github.com/browserify/resolve).
28
29``` js
30var foo = require('./foo.js');
31var bar = require('../lib/bar.js');
32var gamma = require('gamma');
33
34var elem = document.getElementById('result');
35var x = foo(100) + bar('baz');
36elem.textContent = gamma(x);
37```
38
39Export functionality by assigning onto `module.exports` or `exports`:
40
41``` js
42module.exports = function (n) { return n * 111 }
43```
44
45Now just use the `browserify` command to build a bundle starting at `main.js`:
46
47```
48$ browserify main.js > bundle.js
49```
50
51All of the modules that `main.js` needs are included in the `bundle.js` from a
52recursive walk of the `require()` graph using
53[required](https://github.com/defunctzombie/node-required).
54
55To use this bundle, just toss a `<script src="bundle.js"></script>` into your
56html!
57
58# install
59
60With [npm](https://www.npmjs.com/) do:
61
62```
63npm install -g browserify
64```
65
66# usage
67
68```
69Usage: browserify [entry files] {OPTIONS}
70
71Standard Options:
72
73 --outfile, -o Write the browserify bundle to this file.
74 If unspecified, browserify prints to stdout.
75
76 --require, -r A module name or file to bundle.require()
77 Optionally use a colon separator to set the target.
78
79 --entry, -e An entry point of your app
80
81 --ignore, -i Replace a file with an empty stub. Files can be globs.
82
83 --exclude, -u Omit a file from the output bundle. Files can be globs.
84
85 --external, -x Reference a file from another bundle. Files can be globs.
86
87 --transform, -t Use a transform module on top-level files.
88
89 --command, -c Use a transform command on top-level files.
90
91 --standalone -s Generate a UMD bundle for the supplied export name.
92 This bundle works with other module systems and sets the name
93 given as a window global if no module system is found.
94
95 --debug -d Enable source maps that allow you to debug your files
96 separately.
97
98 --help, -h Show this message
99
100For advanced options, type `browserify --help advanced`.
101
102Specify a parameter.
103```
104
105```
106Advanced Options:
107
108 --insert-globals, --ig, --fast [default: false]
109
110 Skip detection and always insert definitions for process, global,
111 __filename, and __dirname.
112
113 benefit: faster builds
114 cost: extra bytes
115
116 --insert-global-vars, --igv
117
118 Comma-separated list of global variables to detect and define.
119 Default: __filename,__dirname,process,Buffer,global
120
121 --detect-globals, --dg [default: true]
122
123 Detect the presence of process, global, __filename, and __dirname and define
124 these values when present.
125
126 benefit: npm modules more likely to work
127 cost: slower builds
128
129 --ignore-missing, --im [default: false]
130
131 Ignore `require()` statements that don't resolve to anything.
132
133 --noparse=FILE
134
135 Don't parse FILE at all. This will make bundling much, much faster for giant
136 libs like jquery or threejs.
137
138 --no-builtins
139
140 Turn off builtins. This is handy when you want to run a bundle in node which
141 provides the core builtins.
142
143 --no-commondir
144
145 Turn off setting a commondir. This is useful if you want to preserve the
146 original paths that a bundle was generated with.
147
148 --no-bundle-external
149
150 Turn off bundling of all external modules. This is useful if you only want
151 to bundle your local files.
152
153 --bare
154
155 Alias for both --no-builtins, --no-commondir, and sets --insert-global-vars
156 to just "__filename,__dirname". This is handy if you want to run bundles in
157 node.
158
159 --no-browser-field, --no-bf
160
161 Turn off package.json browser field resolution. This is also handy if you
162 need to run a bundle in node.
163
164 --transform-key
165
166 Instead of the default package.json#browserify#transform field to list
167 all transforms to apply when running browserify, a custom field, like, e.g.
168 package.json#browserify#production or package.json#browserify#staging
169 can be used, by for example running:
170 * `browserify index.js --transform-key=production > bundle.js`
171 * `browserify index.js --transform-key=staging > bundle.js`
172
173 --node
174
175 Alias for --bare and --no-browser-field.
176
177 --full-paths
178
179 Turn off converting module ids into numerical indexes. This is useful for
180 preserving the original paths that a bundle was generated with.
181
182 --deps
183
184 Instead of standard bundle output, print the dependency array generated by
185 module-deps.
186
187 --no-dedupe
188
189 Turn off deduping.
190
191 --list
192
193 Print each file in the dependency graph. Useful for makefiles.
194
195 --extension=EXTENSION
196
197 Consider files with specified EXTENSION as modules, this option can used
198 multiple times.
199
200 --global-transform=MODULE, -g MODULE
201
202 Use a transform module on all files after any ordinary transforms have run.
203
204 --ignore-transform=MODULE, -it MODULE
205
206 Do not run certain transformations, even if specified elsewhere.
207
208 --plugin=MODULE, -p MODULE
209
210 Register MODULE as a plugin.
211
212Passing arguments to transforms and plugins:
213
214 For -t, -g, and -p, you may use subarg syntax to pass options to the
215 transforms or plugin function as the second parameter. For example:
216
217 -t [ foo -x 3 --beep ]
218
219 will call the `foo` transform for each applicable file by calling:
220
221 foo(file, { x: 3, beep: true })
222
223```
224
225# compatibility
226
227Many [npm](https://www.npmjs.com/) modules that don't do IO will just work after being
228browserified. Others take more work.
229
230Many node built-in modules have been wrapped to work in the browser, but only
231when you explicitly `require()` or use their functionality.
232
233When you `require()` any of these modules, you will get a browser-specific shim:
234
235* [assert](https://www.npmjs.com/package/assert)
236* [buffer](https://www.npmjs.com/package/buffer)
237* [console](https://www.npmjs.com/package/console-browserify)
238* [constants](https://www.npmjs.com/package/constants-browserify)
239* [crypto](https://www.npmjs.com/package/crypto-browserify)
240* [domain](https://www.npmjs.com/package/domain-browser)
241* [events](https://www.npmjs.com/package/events)
242* [http](https://www.npmjs.com/package/stream-http)
243* [https](https://www.npmjs.com/package/https-browserify)
244* [os](https://www.npmjs.com/package/os-browserify)
245* [path](https://www.npmjs.com/package/path-browserify)
246* [punycode](https://www.npmjs.com/package/punycode)
247* [querystring](https://www.npmjs.com/package/querystring-es3)
248* [stream](https://www.npmjs.com/package/stream-browserify)
249* [string_decoder](https://www.npmjs.com/package/string_decoder)
250* [timers](https://www.npmjs.com/package/timers-browserify)
251* [tty](https://www.npmjs.com/package/tty-browserify)
252* [url](https://www.npmjs.com/package/url)
253* [util](https://www.npmjs.com/package/util)
254* [vm](https://www.npmjs.com/package/vm-browserify)
255* [zlib](https://www.npmjs.com/package/browserify-zlib)
256
257Additionally, if you use any of these variables, they
258[will be defined](https://github.com/browserify/insert-module-globals)
259in the bundled output in a browser-appropriate way:
260
261* [process](https://www.npmjs.com/package/process)
262* [Buffer](https://www.npmjs.com/package/buffer)
263* global - top-level scope object (window)
264* __filename - file path of the currently executing file
265* __dirname - directory path of the currently executing file
266
267# more examples
268
269## external requires
270
271You can just as easily create a bundle that will export a `require()` function so
272you can `require()` modules from another script tag. Here we'll create a
273`bundle.js` with the [through](https://www.npmjs.com/package/through)
274and [duplexer](https://www.npmjs.com/package/duplexer) modules.
275
276```
277$ browserify -r through -r duplexer -r ./my-file.js:my-module > bundle.js
278```
279
280Then in your page you can do:
281
282``` html
283<script src="bundle.js"></script>
284<script>
285 var through = require('through');
286 var duplexer = require('duplexer');
287 var myModule = require('my-module');
288 /* ... */
289</script>
290```
291
292## external source maps
293
294If you prefer the source maps be saved to a separate `.js.map` source map file, you may use
295[exorcist](https://github.com/thlorenz/exorcist) in order to achieve that. It's as simple as:
296
297```
298$ browserify main.js --debug | exorcist bundle.js.map > bundle.js
299```
300
301Learn about additional options [here](https://github.com/thlorenz/exorcist#usage).
302
303## multiple bundles
304
305If browserify finds a `require`d function already defined in the page scope, it
306will fall back to that function if it didn't find any matches in its own set of
307bundled modules.
308
309In this way, you can use browserify to split up bundles among multiple pages to
310get the benefit of caching for shared, infrequently-changing modules, while
311still being able to use `require()`. Just use a combination of `--external` and
312`--require` to factor out common dependencies.
313
314For example, if a website with 2 pages, `beep.js`:
315
316``` js
317var robot = require('./robot.js');
318console.log(robot('beep'));
319```
320
321and `boop.js`:
322
323``` js
324var robot = require('./robot.js');
325console.log(robot('boop'));
326```
327
328both depend on `robot.js`:
329
330``` js
331module.exports = function (s) { return s.toUpperCase() + '!' };
332```
333
334```
335$ browserify -r ./robot.js > static/common.js
336$ browserify -x ./robot.js beep.js > static/beep.js
337$ browserify -x ./robot.js boop.js > static/boop.js
338```
339
340Then on the beep page you can have:
341
342``` html
343<script src="common.js"></script>
344<script src="beep.js"></script>
345```
346
347while the boop page can have:
348
349``` html
350<script src="common.js"></script>
351<script src="boop.js"></script>
352```
353
354This approach using `-r` and `-x` works fine for a small number of split assets,
355but there are plugins for automatically factoring out components which are
356described in the
357[partitioning section of the browserify handbook](https://github.com/browserify/browserify-handbook#partitioning).
358
359## api example
360
361You can use the API directly too:
362
363``` js
364var browserify = require('browserify');
365var b = browserify();
366b.add('./browser/main.js');
367b.bundle().pipe(process.stdout);
368```
369
370# methods
371
372``` js
373var browserify = require('browserify')
374```
375
376## `browserify([files] [, opts])`
377
378Returns a new browserify instance.
379
380<dl>
381<dt>
382files
383</dt>
384
385<dd>
386String, file object, or array of those types (they may be mixed) specifying entry file(s).
387</dd>
388
389<dt>
390opts
391</dt>
392
393<dd>
394Object.
395</dd>
396</dl>
397
398`files` and `opts` are both optional, but must be in the order shown if both are
399passed.
400
401Entry files may be passed in `files` and / or `opts.entries`.
402
403External requires may be specified in `opts.require`, accepting the same formats
404that the `files` argument does.
405
406If an entry file is a stream, its contents will be used. You should pass
407`opts.basedir` when using streaming files so that relative requires can be
408resolved.
409
410`opts.entries` has the same definition as `files`.
411
412`opts.noParse` is an array which will skip all require() and global parsing for
413each file in the array. Use this for giant libs like jquery or threejs that
414don't have any requires or node-style globals but take forever to parse.
415
416`opts.transform` is an array of transform functions or modules names which will
417transform the source code before the parsing.
418
419`opts.ignoreTransform` is an array of transformations that will not be run,
420even if specified elsewhere.
421
422`opts.plugin` is an array of plugin functions or module names to use. See the
423plugins section below for details.
424
425`opts.extensions` is an array of optional extra extensions for the module lookup
426machinery to use when the extension has not been specified.
427By default browserify considers only `.js` and `.json` files in such cases.
428
429`opts.basedir` is the directory that browserify starts bundling from for
430filenames that start with `.`.
431
432`opts.paths` is an array of directories that browserify searches when looking
433for modules which are not referenced using relative path. Can be absolute or
434relative to `basedir`. Equivalent of setting `NODE_PATH` environmental variable
435when calling `browserify` command.
436
437`opts.commondir` sets the algorithm used to parse out the common paths. Use
438`false` to turn this off, otherwise it uses the
439[commondir](https://www.npmjs.com/package/commondir) module.
440
441`opts.fullPaths` disables converting module ids into numerical indexes. This is
442useful for preserving the original paths that a bundle was generated with.
443
444`opts.builtins` sets the list of built-ins to use, which by default is set in
445`lib/builtins.js` in this distribution.
446
447`opts.bundleExternal` boolean option to set if external modules should be
448bundled. Defaults to true.
449
450When `opts.browserField` is false, the package.json browser field will be
451ignored. When `opts.browserField` is set to a `string`, then a custom field name
452can be used instead of the default `"browser"` field.
453
454When `opts.insertGlobals` is true, always insert `process`, `global`,
455`__filename`, and `__dirname` without analyzing the AST for faster builds but
456larger output bundles. Default false.
457
458When `opts.detectGlobals` is true, scan all files for `process`, `global`,
459`__filename`, and `__dirname`, defining as necessary. With this option npm
460modules are more likely to work but bundling takes longer. Default true.
461
462When `opts.ignoreMissing` is true, ignore `require()` statements that don't
463resolve to anything.
464
465When `opts.debug` is true, add a source map inline to the end of the bundle.
466This makes debugging easier because you can see all the original files if
467you are in a modern enough browser.
468
469When `opts.standalone` is a non-empty string, a standalone module is created
470with that name and a [umd](https://github.com/forbeslindesay/umd) wrapper.
471You can use namespaces in the standalone global export using a `.` in the string
472name as a separator, for example `'A.B.C'`. The global export will be [sanitized
473and camel cased](https://github.com/ForbesLindesay/umd#name-casing-and-characters).
474
475Note that in standalone mode the `require()` calls from the original source will
476still be around, which may trip up AMD loaders scanning for `require()` calls.
477You can remove these calls with
478[derequire](https://www.npmjs.com/package/derequire):
479
480```
481$ npm install -g derequire
482$ browserify main.js --standalone Foo | derequire > bundle.js
483```
484
485`opts.insertGlobalVars` will be passed to
486[insert-module-globals](https://www.npmjs.com/package/insert-module-globals)
487as the `opts.vars` parameter.
488
489`opts.externalRequireName` defaults to `'require'` in `expose` mode but you can
490use another name.
491
492`opts.bare` creates a bundle that does not include Node builtins, and does not
493replace global Node variables except for `__dirname` and `__filename`.
494
495`opts.node` creates a bundle that runs in Node and does not use the browser
496versions of dependencies. Same as passing `{ bare: true, browserField: false }`.
497
498Note that if files do not contain javascript source code then you also need to
499specify a corresponding transform for them.
500
501All other options are forwarded along to
502[module-deps](https://www.npmjs.com/package/module-deps)
503and [browser-pack](https://www.npmjs.com/package/browser-pack) directly.
504
505## b.add(file, opts)
506
507Add an entry file from `file` that will be executed when the bundle loads.
508
509If `file` is an array, each item in `file` will be added as an entry file.
510
511## b.require(file, opts)
512
513Make `file` available from outside the bundle with `require(file)`.
514
515The `file` param is anything that can be resolved by `require.resolve()`,
516including files from `node_modules`. Like with `require.resolve()`, you must
517prefix `file` with `./` to require a local file (not in `node_modules`).
518
519`file` can also be a stream, but you should also use `opts.basedir` so that
520relative requires will be resolvable.
521
522If `file` is an array, each item in `file` will be required.
523In `file` array form, you can use a string or object for each item. Object items
524should have a `file` property and the rest of the parameters will be used for
525the `opts`.
526
527Use the `expose` property of opts to specify a custom dependency name.
528`require('./vendor/angular/angular.js', {expose: 'angular'})` enables `require('angular')`
529
530## b.bundle(cb)
531
532Bundle the files and their dependencies into a single javascript file.
533
534Return a readable stream with the javascript file contents or
535optionally specify a `cb(err, buf)` to get the buffered results.
536
537## b.external(file)
538
539Prevent `file` from being loaded into the current bundle, instead referencing
540from another bundle.
541
542If `file` is an array, each item in `file` will be externalized.
543
544If `file` is another bundle, that bundle's contents will be read and excluded
545from the current bundle as the bundle in `file` gets bundled.
546
547## b.ignore(file)
548
549Prevent the module name or file at `file` from showing up in the output bundle.
550
551If `file` is an array, each item in `file` will be ignored.
552
553Instead you will get a file with `module.exports = {}`.
554
555## b.exclude(file)
556
557Prevent the module name or file at `file` from showing up in the output bundle.
558
559If `file` is an array, each item in `file` will be excluded.
560
561If your code tries to `require()` that file it will throw unless you've provided
562another mechanism for loading it.
563
564## b.transform(tr, opts={})
565
566Transform source code before parsing it for `require()` calls with the transform
567function or module name `tr`.
568
569If `tr` is a function, it will be called with `tr(file)` and it should return a
570[through-stream](https://github.com/substack/stream-handbook#through)
571that takes the raw file contents and produces the transformed source.
572
573If `tr` is a string, it should be a module name or file path of a
574[transform module](https://github.com/browserify/module-deps#transforms)
575with a signature of:
576
577``` js
578var through = require('through');
579module.exports = function (file) { return through() };
580```
581
582You don't need to necessarily use the
583[through](https://www.npmjs.com/package/through) module.
584Browserify is compatible with the newer, more verbose
585[Transform streams](http://nodejs.org/api/stream.html#stream_class_stream_transform_1)
586built into Node v0.10.
587
588Here's how you might compile coffee script on the fly using `.transform()`:
589
590``` js
591var coffee = require('coffee-script');
592var through = require('through');
593
594b.transform(function (file) {
595 var data = '';
596 return through(write, end);
597
598 function write (buf) { data += buf }
599 function end () {
600 this.queue(coffee.compile(data));
601 this.queue(null);
602 }
603});
604```
605
606Note that on the command-line with the `-c` flag you can just do:
607
608```
609$ browserify -c 'coffee -sc' main.coffee > bundle.js
610```
611
612Or better still, use the [coffeeify](https://github.com/jnordberg/coffeeify)
613module:
614
615```
616$ npm install coffeeify
617$ browserify -t coffeeify main.coffee > bundle.js
618```
619
620If `opts.global` is `true`, the transform will operate on ALL files, despite
621whether they exist up a level in a `node_modules/` directory. Use global
622transforms cautiously and sparingly, since most of the time an ordinary
623transform will suffice. You can also not configure global transforms in a
624`package.json` like you can with ordinary transforms.
625
626Global transforms always run after any ordinary transforms have run.
627
628Transforms may obtain options from the command-line with
629[subarg](https://www.npmjs.com/package/subarg) syntax:
630
631```
632$ browserify -t [ foo --bar=555 ] main.js
633```
634
635or from the api:
636
637```
638b.transform('foo', { bar: 555 })
639```
640
641In both cases, these options are provided as the second argument to the
642transform function:
643
644```
645module.exports = function (file, opts) { /* opts.bar === 555 */ }
646```
647
648Options sent to the browserify constructor are also provided under
649`opts._flags`. These browserify options are sometimes required if your transform
650needs to do something different when browserify is run in debug mode, for
651example.
652
653## b.plugin(plugin, opts)
654
655Register a `plugin` with `opts`. Plugins can be a string module name or a
656function the same as transforms.
657
658`plugin(b, opts)` is called with the browserify instance `b`.
659
660For more information, consult the plugins section below.
661
662## b.pipeline
663
664There is an internal
665[labeled-stream-splicer](https://www.npmjs.com/package/labeled-stream-splicer)
666pipeline with these labels:
667
668* `'record'` - save inputs to play back later on subsequent `bundle()` calls
669* `'deps'` - [module-deps](https://www.npmjs.com/package/module-deps)
670* `'json'` - adds `module.exports=` to the beginning of json files
671* `'unbom'` - remove byte-order markers
672* `'unshebang'` - remove #! labels on the first line
673* `'syntax'` - check for syntax errors
674* `'sort'` - sort the dependencies for deterministic bundles
675* `'dedupe'` - remove duplicate source contents
676* `'label'` - apply integer labels to files
677* `'emit-deps'` - emit `'dep'` event
678* `'debug'` - apply source maps
679* `'pack'` - [browser-pack](https://www.npmjs.com/package/browser-pack)
680* `'wrap'` - apply final wrapping, `require=` and a newline and semicolon
681
682You can call `b.pipeline.get()` with a label name to get a handle on a stream pipeline
683that you can `push()`, `unshift()`, or `splice()` to insert your own transform
684streams.
685
686## b.reset(opts)
687
688Reset the pipeline back to a normal state. This function is called automatically
689when `bundle()` is called multiple times.
690
691This function triggers a 'reset' event.
692
693# package.json
694
695browserify uses the `package.json` in its module resolution algorithm, just like
696node. If there is a `"main"` field, browserify will start resolving the package
697at that point. If there is no `"main"` field, browserify will look for an
698`"index.js"` file in the module root directory. Here are some more
699sophisticated things you can do in the package.json:
700
701## browser field
702
703There is a special "[browser](https://github.com/defunctzombie/package-browser-field-spec)" field you can
704set in your package.json on a per-module basis to override file resolution for
705browser-specific versions of files.
706
707For example, if you want to have a browser-specific module entry point for your
708`"main"` field you can just set the `"browser"` field to a string:
709
710``` json
711"browser": "./browser.js"
712```
713
714or you can have overrides on a per-file basis:
715
716``` json
717"browser": {
718 "fs": "level-fs",
719 "./lib/ops.js": "./browser/opts.js"
720}
721```
722
723Note that the browser field only applies to files in the local module, and like
724transforms, it doesn't apply into `node_modules` directories.
725
726## browserify.transform
727
728You can specify source transforms in the package.json in the
729`browserify.transform` field. There is more information about how source
730transforms work in package.json on the
731[module-deps readme](https://github.com/browserify/module-deps#transforms).
732
733For example, if your module requires [brfs](https://www.npmjs.com/package/brfs), you
734can add
735
736``` json
737"browserify": { "transform": [ "brfs" ] }
738```
739
740to your package.json. Now when somebody `require()`s your module, brfs will
741automatically be applied to the files in your module without explicit
742intervention by the person using your module. Make sure to add transforms to
743your package.json dependencies field.
744
745# events
746
747## b.on('file', function (file, id, parent) {})
748## b.pipeline.on('file', function (file, id, parent) {})
749
750When a file is resolved for the bundle, the bundle emits a `'file'` event with
751the full `file` path, the `id` string passed to `require()`, and the `parent`
752object used by
753[browser-resolve](https://github.com/defunctzombie/node-browser-resolve).
754
755You could use the `file` event to implement a file watcher to regenerate bundles
756when files change.
757
758## b.on('package', function (pkg) {})
759## b.pipeline.on('package', function (pkg) {})
760
761When a package file is read, this event fires with the contents. The package
762directory is available at `pkg.__dirname`.
763
764## b.on('bundle', function (bundle) {})
765
766When `.bundle()` is called, this event fires with the `bundle` output stream.
767
768## b.on('reset', function () {})
769
770When the `.reset()` method is called or implicitly called by another call to
771`.bundle()`, this event fires.
772
773## b.on('transform', function (tr, file) {})
774## b.pipeline.on('transform', function (tr, file) {})
775
776When a transform is applied to a file, the `'transform'` event fires on the
777bundle stream with the transform stream `tr` and the `file` that the transform
778is being applied to.
779
780# plugins
781
782For some more advanced use-cases, a transform is not sufficiently extensible.
783Plugins are modules that take the bundle instance as their first parameter and
784an option hash as their second.
785
786Plugins can be used to do perform some fancy features that transforms can't do.
787For example, [factor-bundle](https://www.npmjs.com/package/factor-bundle) is a
788plugin that can factor out common dependencies from multiple entry-points into a
789common bundle. Use plugins with `-p` and pass options to plugins with
790[subarg](https://www.npmjs.com/package/subarg) syntax:
791
792```
793browserify x.js y.js -p [ factor-bundle -o bundle/x.js -o bundle/y.js ] \
794 > bundle/common.js
795```
796
797For a list of plugins, consult the
798[browserify-plugin tag](https://www.npmjs.com/browse/keyword/browserify-plugin)
799on npm.
800
801# list of source transforms
802
803There is a [wiki page that lists the known browserify
804transforms](https://github.com/browserify/browserify/wiki/list-of-transforms).
805
806If you write a transform, make sure to add your transform to that wiki page and
807add a package.json keyword of `browserify-transform` so that
808[people can browse for all the browserify
809transforms](https://www.npmjs.com/browse/keyword/browserify-transform) on npmjs.org.
810
811# third-party tools
812
813There is a [wiki page that lists the known browserify
814tools](https://github.com/browserify/browserify/wiki/browserify-tools).
815
816If you write a tool, make sure to add it to that wiki page and
817add a package.json keyword of `browserify-tool` so that
818[people can browse for all the browserify
819tools](https://www.npmjs.com/browse/keyword/browserify-tool) on npmjs.org.
820
821# changelog
822
823Releases are documented in
824[changelog.markdown](changelog.markdown) and on the
825[browserify twitter feed](https://twitter.com/browserify).
826
827# license
828
829[MIT](./LICENSE)
830
831![browserify!](./assets/browserify.png)