Web developers owe a great deal to npm JavaScript libraries. npm packages resolve common web problems in elegant ways, are free to use, rock solid (potentially tested by thousands of users) and save development efforts. No doubt npm makes our lives easier but... who are those anonymous open source heroes? Well, you can be the next one!
Why creating a Javascript library?
- To help yourself: How many times did you start implementing a feature in a project and suddenly remember about a time you did something similar in another project? Instead of copy and pasting the code from one repository to the other you can create a new repository to hold contain piece of code in a single place. It will be easier to for you to maintain it and you can add some usage examples so that next time you want to use it, you will easily remember how to do so.
- To become a better developer: Writing code for others is much more demanding than writing it for yourself or your team. When creating a library, you must focus on the library behavior, making the Api as simple and intuitive as possible. When turning your killer code into a library you will end up understanding better it's intention and you might be surprised to discover design flaws or unnoticed dependencies.
- To make the world a better place: In the same way you can reuse that brilliant utilities others might also find them useful. Aren't you grateful when you find an npm package that does exactly what you need? Then wait no more to start contributing back to the community. Plus the more people there is running your code the more your library will evolve and become better. redux is an excellent example of a library that was started by a single developer and is now used by millions, having received contributions from over 800 developers.
- To feed your ego: Last but not least! Nothing can make a developer more proud of himself than having conceived and developed a library that people use 😎 Even if the only user of the library is the developer himself (I can tell from personal experience).
How to publish a Javascript library to npm
Publishing a package to npm is rather easy; you just need to create an account and upload the package by running the following command within your project directory. In fact, you can upload any type of file inside an npm package; from your parents wedding video to a pdf version of the bible. The tricky part of publishing a package is actually to make it easy to use and understand, while keeping it small-sized, functioning and properly versioned.
Here is a checklist you want to cover in order to build a great library:
- README.md: Help potential users of your library understanding what it does and how it works through this markdown introduction file. It typically contains a description of the library goal, usage examples and eventually some links to relevant content (e.g. official documentation page). npm will display the information in this file in the npm package page, just as Github does when accessing a repository (no wonder they encourage you to add a README file to all your repositories):
- Versioning: both npm and users identify different releases of your library by the version field of your package.json file. If you try to publish a new release of your package without changing the version number, npm will throw an error. Get familiar with semantic versioning and make sure you properly update the version depending on the type of your release:npm version [major|minor|patch]
- .npmignore: Web developers are sensitive to libraries size so it's in your interest to keep yours small. Plus, uploading useless files to npm only consumes network bandwidth and storage space in npm servers; be a good samaritan and keep your garbage away. This file tells npm which files to exclude when publishing a package. Typical files you will want to exclude are the tests, reports and the source files if you are using a transpiler.
- Testing: Prevent breaking old features while developing new ones by writing tests and running them before every publish. Nothing bothers developers more than a broken feature due to a library update. Plus, users will find out about the issues hours later of your release; you will find yourself rushing to revert the changes or fix the issues and publishing a new version. Great open source libraries always come with great testing.
- Types declaration: Help users understanding how to use your library by providing types declaration. You do that by exporting your library types from a .d.ts typescript file (automatically generated by the typescript compiler when enabling the declaration option) and referencing that file from the types field of your package.json. If don't use Typescript in your library, you can manually generate the file. You will get visual studio code to display all the available properties in your components:
- Transpiling: A common error when using transpilers (e.g. Typescript, babel, etc.) is to publish a new version of the library without transpiling the code first. Force npm to build your project before each release by adding a prepublishOnly script in your package.json. Typically it will just run the build command. I also like to remove the entire distribution folder to prevent publishing old files.
Some examples
Need some inspiration to get you started? Here are some examples which, what a coincidence, happen to be developed by me. Luckily, they will help preventing you from making the same mistakes:
- cucumber-steps-parser: Simple library I developed while working at Sage that searches for all the cucumber.js sentence definitions in a Javascript/Typescript project. The first version was not very intuitive, so the second had a slightly more descriptive api. Accepting config options in an optional argument (v2) is always more descriptive having many optional arguments (v1):
- react-redux-link: Monkey patching of the react-redux package. I wrote the code (145 lines in total) as a part of another project and realized it was generic enough to exist on its own. The proof that there is no minimal functionality level a library must provide.
It provides type safety when connecting the react components to the redux store, highlighting missing properties and bad types. It requires to declare the component properties interface using ReduxComposedProps and replace the react-redux connect with link: - modena: Web server that allows exposing multiple express apps on a single domain isolated from each other. The first version was meant to make the hosted apps code as light as possible, but it turned out to be a total mess.
It imposed restrictions on the hosted apps (e.g. EJS template language, passport.js for authentication, the route of the static assets, etc.) and forced them to install modena as a dependency and use it to define the express routes (making it hard to run the app as standalone). It also included non related functionalities (such as dynamic SASS compilation) which made the library heavier for features that most times wouldn't be used.
A library that provides features on top of other libraries must respect those libraries conventions. I had no other option to re-write the library from scratch, removing the non-related features and keeping in mind that hosted apps existed in their own. Making a library too rigid will only result in nobody using it.
And that's all there is! Wait no more and go publishing your brand new library 💪