How do you use the 'files' and 'directories' properties in package.json?

"include in your project" means the files will be in the packaged tarball that is created when you run npm publish. You can also run npm pack to generate the tarball for inspection without actually triggering a publish. This way you can actually open the generated tarball and inspect which files were/were not included.

While .npmignore (or .gitignore as a proxy, if no .npmignore) functions as a black list of files to ignore (thereby including everything else by default), the files array is a whitelist. That is, instead of including everything by default, if files array is specified everything is excluded by default and only those files explicitly listed will be included in the packaged tarball.

As an example, say your package is a library meant for consumption in the browser. Your code is in lib/, and you run browserify to compile into a browser-compatible lib at dist/index.js. You start out with a bunch of files listed in .gitignore, which is used as the defacto .npmignore which doesn't exist. But now that dist/ is full of generated files, you want them ignored from the git repo. If you add them to .gitignore, they will be excluded from the git repo, but they will also be ignored from the package tarball. So you have two options: duplicate your .gitignore as .npmignore but only list dist/ in .gitignore. If you do this, you will have to keep two files almost-but-not-quite in sync. This way is tedius and error-prone.

The other alternative is to not have a .npmignore, and instead just list the files you actually want in the package, in the files array. README.*, package.json, CHANGELOG.* (maybe a couple others) are automatically included in the tarball regardless. So you simply add "files": [ "dist" ] and you're done. Now your package tarball won't include original source JS from lib, nor tests/ etc but will instead only contain the actual compiled lib in dist/.

As for directories, I typically list the lib (for es5), src (for es6, coffeescript, typescript etc sources), dist (for browser or vm-specific builds), test, output (for temporary generated files like coverage reports, etc), doc, etc. Though this property isn't used directly by npm or other tools, it makes the directory structure explicit. Also, it makes the directories referenceable in npm scripts like so:

"scripts": {
  "clean": "rm -rf $npm_package_directories_dist $npm_package_directories_output",
  "lint": "eslint $npm_package_directories_src",
  "test": "teenytest $npm_package_directories_test",
}

In this way, the directories are specified only once, and if they change, they only need changed in a single location (rather than many throughout the package.json).