let's write better node modules
DESCRIPTION
Talk for Node Summit 2013 - some guidelines for publishing node modules that move the community forwardTRANSCRIPT
Copyright © twilio Inc. 2013
LET’S BUILD BETTER NODE MODULES
NODE SUMMIT
DECEMBER 2013
HI. I’M KEVIN.developer evangelist @ twilio
What is twilio?
twilio makes it easy for developers to integrate voice calling and messaging into web and native mobile applications
“The goal is to have lots of user-created modules, that are all single-purpose and focused...so you can iterate get the best
experience possible...”
49,000PACKAGES
PyPI: ~37K | RubyGems: ~67K | NuGet: ~18K
6,000,000+DOWNLOADS PER DAY
USERLAND CARRIES A HEAVY LOAD
request
optimist
connect
lodash
0 0.35 0.7 1.05 1.4
Downloads in millions for October
IF USERLAND SUCKS,NODE SUCKS.
• Provide accurate documentation optimized for how people read on the internet (scanning and searching)
• Design idiomatic APIs that optimize for the job your module will be hired to do
• Implement test automation and basic release management
HOW WE CAN HELP
DOCUMENTATION
• Very few userland modules have effective docs - common open source problem
• Every module has different documentation needs
• Great resource: Kevin Burke’s talk on this subject
• Two most important components for node modules:
• README (quick start)
• API Docs
DOCUMENT ALL THE THINGS
• Focus on the job your module will be “hired” to do
• Get user to success ASAP by staying focused:
• What job does your module do?
• How do you install/configure it?
• ~3 examples of how to do the thing your module would be hired to do
• Link to API docs and deeper info sources
AN EFFECTIVE README
• Mongoose: https://npmjs.org/package/mongoose
• jsdom: https://npmjs.org/package/jsdom
• browserify: https://npmjs.org/package/browserify
• request: https://npmjs.org/package/request
• node-uuid: https://npmjs.org/package/node-uuid
CASE STUDIES
• Describe the complete surface area of the API
• Provide context for how the API is meant to be used
• Make content readable and scannable
• Provide complete and correct examples, but do not rely on them as API documentation
• “Read the tests” is a cop out (see above)
EFFECTIVE API DOCS
• Document all properties and functions from module.exports (harder than it sounds)
• Document all function signatures
• Function docs should ideally have:
• Return value/type
• Argument types
• Example usage
DESCRIBING A NODE.JS API
• Show how your code is intended to be used
• Demonstrate how it interconnects with other modules/platform features
• Describe high-level use cases and concepts unique to your module
PROVIDING CONTEXT
• Users don’t read docs word for word - they scan in an F shape, looking for relevant bits
• Include a table of contents for longer content (https://github.com/thlorenz/doctoc)
• Make the first 3-5 words of every line contain the most information possible
• Use headers/images/code to break up scary blocks of text
• Limit text on a page to columns of ~80 characters
MAKE CONTENT READABLE
• Reinforce written docs with sample code that shows actual usage
• Ideally, examples should be copy/cut/paste ready - include any necessary setup/teardown, including the “require”
• Accuracy is key - broken examples are super frustrating
PROVIDE EXAMPLES
• Mongoose: http://mongoosejs.com/index.html
• express: http://expressjs.com/api.html
• browserify: https://github.com/substack/node-browserify
• request: https://github.com/mikeal/request
• node-uuid: https://npmjs.org/package/node-uuid
CASE STUDIES
API DESIGN
• Check out: https://www.youtube.com/watch?v=aAb7hSCtvGw
• Design for async usage
• Use streams for I/O
• Be mindful of the job your module has been hired to do
NODE.JS MODULE API DESIGN
• Do not release Zalgo
• Node core modules use a specific type of signature for async APIs that require callbacks
• Function takes whatever arguments, and a callback
• Callback is called with any error received as the first argument, formatted data is the second.
• Sometimes there’s a third arg with a “raw” value in userland
DESIGNING FOR ASYNC
• If you do any sort of I/O, you’d do well to make your interface speak streams
• Your API will interoperate well with the rest of the node ecosystem if you work with readable and writable streams
• “When you grok streams, you grok node” - Isaac paraphrase
DESIGN FOR STREAMS
• Your module might do a few different things, but it probably has a few 80% use cases
• Your API should be designed to do those jobs as quickly and efficiently as possible, with sensible default behavior
BE MINDFUL OF YOUR PURPOSE
• browserify: https://github.com/substack/node-browserify
• request: https://github.com/mikeal/request
• twilio: http://twilio.github.io/twilio-node
CASE STUDIES
TESTING AND RELEASES
MANAGING YOUR PROJECT
• Ensure quality with testing and test automation (which can be super easy)
• Ensure sanity with your module releases by using semantic versioning
MANAGING YOUR PROJECT
• Promote quality with testing and test automation (which can be super easy)
• Ensure sanity with your module releases by using semantic versioning
TESTING/AUTOMATION
• Lots of great test frameworks, pick your favorite or just use assert
• Do support “npm test”
• Travis CI is your friend, and super easy to set up
RELEASE MANAGEMENT
• If you follow semantic versioning, you’re probably doing fine
• If an API breaks from 1.4 to 1.5, that’s a Very Bad Thing
• Use git tags that match your npm versions
• Doing the above makes release notes/change log very easy
• twilio: http://twilio.github.io/twilio-node
CASE STUDIES
WRAPPING UP
• You probably don’t get paid to write and share your module - thank you for contributing!
• node.js relies on userland modules more than any other major server-side platform
• If we care about the node ecosystem and community, we all have to step up with the quality of our contributions
THANK YOU!@[email protected]
http://github.com/kwhinneryhttp://slideshare.net/kwhinnery