On creating my first public npm package
What I've learned publishing my first npm module
Introduction
So, I created and published an npm module. It’s available, people are using it - ok, a few people, 105 weekly downloads at the time of writing -, someone opened a Pull Request, someone opened a bug, I updated the module a couple of times.
Why did I do that?
We were developing a cross-platform mobile app in React Native and needed a very simple thing, the so-called “advertising ID”, some unique UUID used for tracking purposes, called IDFA in the iOS world and AAID in Android. This is a string that you can pass to any vendor using their API, regardless of being generated by an Apple or Android phone. The logic for obtaining this string is very simple, but quite different in the two worlds. For example, on iOS you need to ask the user for a specific permission (AppTrackingTransparency) and on Android you can rely on the AdMob library or on a specific AAID interface.
So I quickly developed a very simple code for accessing this native device feature, but then I realized that it would have been simpler and more portable to just wrap it all into a module, making it also available for other projects. Next standup I proposed to develop an npm module, and I was ready to begin.
With this post I want to tell you my experience and try to guide you towards creating and publishing an npm module!
STEPS
React Native
When we started our journey into mobile development we wanted to be as close as possible to our “comfort zone”, our web development stack, so of course Docker, node and JavaScript. The two most reliable JS frameworks that we found were Ionic and React Native, and the latter was the most impressive in terms of performances, community and third-party integrations, so we decided to make it our reference framework. Plus, we already had some experience with React so even though Ionic was closer to our coding habits (it’s basically pure React) switching to Native felt quite natural.
React Native is a JavaScript framework for building cross-platform native apps using React, developed by Facebook. It lets you write apps in React and then produces native code, so you can take advantage of the best of both worlds.
IDFA & AAID
IDFA (Identifier for Advertising) and AAID (Google Advertising ID) are unique identifiers specific for every device that allow developers and marketers to track activity for advertising purposes. Users can opt-out at any time, or reset their identifier.
First reaction: Bob!
I wanted a quick starterkit for my module, like a boilerplate to clone and start coding, but then I found a command line tool to scaffold a new React Native library: bob!
Scaffolding a new library with Bob is as easy as:
npx create-react-native-library react-native-awesome-module
This simple command asks you some questions in a wizard and then creates a folder with an npm module that by default exports a simple string, but the magic of React Native is that this simple string is returned by a Kotlin or Swift code, respectively for Android and iOS. Starting here you can simply edit this code to add your specific logic, import whatever native library you want and expose the return value back to the JavaScript module, in a Promise.
The native code needed for this feature is very small so I just wrapped the return value in a resolve
callback, after checking permissions and dealing with errors, and that’s it.
Bob also adds useful tools like jest
, eslint
and prettier
, an example React Native project to test your module and the release-it
tool that we’ll use later for publishing.
Bob is specific for React Native, but there are many scaffolding tools for any kind of frameworks out there. You could also start from a simple npm init
, and export something from your module that other projects may reuse!
Testing the module locally
So you have your wonderful npm module, you tested it with the example app provided, how can you test the integration with your React Native app running locally? The answer is npm-link
.
npm-link is a cli tool for testing a local package. It basically creates a symlink from your project to your local npm module. The best explanation is with an example:
cd ~/projects/node-redis # go into the package directory
npm link # creates global link
cd ~/projects/node-bloggy # go into some other package directory.
npm link redis # link-install the package
Now, any changes to ~/projects/node-redis
will be reflected in ~/projects/node-bloggy/node_modules/node-redis/
. You just need to link the package name, no need to remember the directory path.
This is great! You have a local npm module and you can just import it to any local project, make some changes, rebuild it and live test!
You are ready to publish…but first you need one last thing.
Writing a good README
Every successful open source project comes with a nice README file. People who reach for your project need to quickly understand if it solves the problem they have, so in the first paragraph you should state what’s the purpose of your module and a bit of context, for example if it’s for a specific OS/language or has some hard dependencies.
Then you should list the necessary steps to install, include and run it, and every code snippet could help a potential user or other members of your team understand how to use it, even yourself a couple of months after you finish it!
I based mine on a simple template, including a contribution guide and a license, you should find the one that best suits your needs.
Publishing to npm
Finally! You finished your library and you pushed the code to GitHub (this is optional, but really recommended). Now you’re ready to publish to npmjs.com!
This is really easy and it just involves three steps:
create a new user on npmjs.com
login via command line using npm login
publish via command line using npm publish
That’s it! Well, that’s if you want to manually manage versioning and all tasks related to package publishing. Because you will have bugfix and new features, and you will have to manage package updates.
But another npm tool comes in handy: Release It! 🚀
release-it
is a command-line tool that automates all the tasks involved in a new npm release, like commit, tag, push to GitHub and publish to npm.
Once added to your repository, you can add package.json
scripts and even configure the commit message format, and hooks pre and post release.
Eventually, the process of taking a bugfix to the production package can become something like: npm run release minor
You can be even more specific, the tool will show you a wizard but you can configure most of it through command line arguments.
Conclusions
Publishing a library to npm is one of the coolest things you can do as a JavaScript developer. You know that what you did can become useful to others, your project will be used, included as a dependency, you will receive bug reports, feature requests, pull requests by people who want to extend it.
In my opinion the whole process is really easy to understand and master, and in the end it can become as natural as creating a git commit
and pushing code to GitHub.
So whenever you think even the smallest thing you wrote might be useful for someone else, wrap it in a node package and publish it on npmjs.com!
October update
The module reached 1.500 weekly downloads on npm in october 2021, so I guess it’s pretty stable! And we are continuing to work on it and support it, road to v1.0!