A little background
Before we begin, I would like to share with you with my personal opinion about the topic. Feel free to discuss this in the comments below.
So, of course, 1M packages is a great success, or is it? If you're someone who has been into the JS ecosystem for quite a while now, you know how the situation really looks like. And, while 1M is indeed an impressive number, I think we all agree that only a small fraction of these packages are actually useful. A great chunk of them is just a big mess - a graveyard of code that many of us (JS developers) contributed to. That's where these numbers come from. But why? Well, maybe it's because of NPM's simplicity? JavaScript's popularity has grown exponentially in recent times, and with that - NPM registry. The JS code that NPM houses is simple and portable - just like the registry itself. This brings the "entry level" pretty low, allowing beginners and starters to use it just like that. Naturally, it's a great pro for NPM, just one that leads to some concerning consequences.
If someone says to just "snap in half the whole NPM registry" - it's not that easy. Sure, it'll work for "dead packages", but this would solve only a very small piece of the problem. You see, many packages, even these unmaintained and unpopular ones, are still used by some different people. Removing them completely would result in these people's projects getting crashed. You might, of course, mark the package as deprecated, hope people will listen, and then remove it after some time, but is this really a solution?
Finally, we know that these numbers show something important about how the development process has changed over the last few years. From writing everything alone, through jQuery and CDNs, to NPM (for now). Because of that, you can arguably just install a whole bunch of NPM packages, copy some snippets, and you have a nice demo for JIT presentation ;). That's somewhat fun, but also quite scary fact. You should remember to use NPM packages to your advantage, but don't over-rely on them to form the majority of your mainline code-base.
Also, NPM is managed by a company - NPM. That's why some concerned people might have problems with embracing it. Because of the lack of any comparable alternatives (although some work is being done in this regard), and only a few mirrors (like Yarn's), you can never be sure of the future of packages you use or create. It's kind-of a trust-based agreement over there, that (at least for now) has been working pretty well. Now - to the list!
Ranking
Now, to be clear, let's define first what I mean by "popular" packages. That's because this list may differ, depending on the way you look at it. Take the most downloaded packages for example. They include both the ones downloaded directly, as well as the ones that are sub-dependencies of other packages. This would lead to packages like Yargs being much closer to the top when compared to e.g. React. With that said, in this post, "popular" means a package with rather highest numbers of downloads, when compared to all others. Of course, as the way package was downloaded can be quite hard to determine, and as such, we'll base the ranking mostly on some logical thinking and raw weekly downloads count.
10. React
With around 5M weekly downloads, it's no surprise that React appeared in this list. Even though Vue exceed React in terms of GitHub stars last year, NPM statistics clearly show, which UI tool is more used. This means, that React still holds its title of the most popular UI library. Besides that, I think it needs no further introduction.
9. Prop-types
Prop-types is the second React-related package on this list. As the name suggests, it's a small library for making your React components type-safe by allowing you to add types to your props. React's official documentation does a fairly good job of explaining the concept.
import PropTypes from 'prop-types'; class Greeting extends React.Component { render() { return ( <h1>Hello, {this.props.name}</h1> ); } } Greeting.propTypes = { name: PropTypes.string };
Of course, the library works at runtime, but you can process it out pretty easily for better performance at the production stage.
Personally, I've never used this library. As I'm a user and a great fan of TypeScript, such tooling is unnecessary for me. The same goes for Flow users. The integration that these languages/type checkers provide is just far better than what prop-types can offer. Naturally, that's very understandable, as the library is for type-checking React props only. If you want to introduce superior type-safety to your project, I still recommend that you go with TypeScript.
8. Moment
Moving away from React we find Moment.js - one of the most stable & maintained time manipulation libraries you can find. In the whole collection of libraries, created to solve the issues of formatting, parsing, converting and, generally, working with different forms of time, Moment.js is the one that has seen the widest adoption.
import moment from "moment"; // in relation to release date of this post moment().format("MMMM Do YYYY"); // June 6th 2019 moment("20111031", "YYYYMMDD").fromNow(); // 8 years ago moment().subtract(10, "days").calendar(); // 05/27/2019
With its latest v2 release, Moment.js got rewritten, to support latest ES6 syntax. This brings improved modularity and better performance for always-green browsers. Such things are important, especially when dealing with a library as big as Moment.js (~66 KB min-zipped)!
7. Express
Express is a web framework, most likely known to everyone, who worked with Node.js and did some backend development. Serving as a higher abstraction layer over a bit more complex Node.js API, Express provides almost everything you need to create your own, full-blown backend.
import express from "express"; const app = express(); app.get("/", function (req, res) { res.send("Hello World"); }); app.listen(3000);
Because of Express' extendability through its middleware architecture and relatively minimalistic and "unopinionated" API, Express is also used as a base for many other backend frameworks, e.g. Feathers.
6. Request
The 14M weekly downloads score shows, just how important the basic HTTP functionality really is. Ease-of-use, asynchronicity, singular API and great Node.js File System API integration are only some of the pros of this library.
import request from "request"; request("http://www.google.com", (error, response, body) => { console.log("error:", error); console.log("statusCode:", response && response.statusCode); console.log("body:", body); });
In terms of functionality and API, Request greatly resembles the rather-new Fetch API. The most notable advantages of this library over the native solution includes the support for Node.js and across-the-board compatibility for different browsers. Still, the similarities in the API makes the possible switch easy and convenient - one way or another.
5. Lodash
Who doesn't know Lodash? The most popular and widely-used JS utility library. A great number of libraries, tools, and projects depend on it. Even the ones not using it (myself included) must admit its usefulness, at least in some cases. Fast, modular and full-featured - what more do you want?
import _ from "lodash"; _.defaults({ a: 1 }, { a: 3, b: 2 }); // { 'a': 1, 'b': 2 } _.partition([1, 2, 3, 4], n => n % 2); // [[1, 3], [2, 4]]
4. Async
Like Lodash is a utility library for general JS, Async is the same for - you guessed it - async JS! There're around 70 different functions responsible for async iterations, operations and more.
import async from "async"; import fs from "fs"; /* fs.stat and the whole Node.js FS API is a great example of asynchronous methods */ async.map(["file1", "file2", "file3"], fs.stat, (err, results) => { results; // array of files stats });
Also, the library can be used with callbacks, promises or the newest await/async syntax!
3. Chalk
With Chalk, we're entering the world of terminal-related tools and libraries, where a number of downloads, and thus popularity, goes crazy! Chalk is an extremely simple library, created for one, simple purpose - styling your terminal strings! Just like with Require - it proves that the most useful things are also the simplest ones.
import chalk from "chalk'); // string concatenation - template literals console.log(`${chalk.blue("Hello")} World${chalk.red("!")}`); // chainable API console.log(chalk.blue.bgRed.bold("Hello world!"));
Of course, the API is simple, intuitive (chainable) and it works really well with all features that JS has to offer natively. The official page of the packages states that it's used by more than 20K different packages! Maybe that's where the weekly downloads count comes from (~25M). Even though, such numbers cannot be ignored.
2. Commander
Commander.js is a simple and very lightweight solution for creating Node.js terminal applications. With a small set of functions, it makes creating CLI apps relatively fun and easy.
import program from "commander"; program .version("0.1.0") .option("-p, --peppers", "Add peppers"); .option("-P, --pineapple", "Add pineapple"); .option("-b, --bbq-sauce", "Add bbq sauce"); .option("-c, --cheese [type]", "Add the specified type of cheese [marble]", "marble"); .parse(process.argv);
Because of the Commander's overall design and ideology, it doesn't provide a ton of features. Still, it's enough for even some complex cases.
When getting started with creating CLI apps, you need to distinguish between libraries like Commander.js and Inquirer.js (12M). While Commander allows you to easily manage your app "behind the scenes", Inquirer makes its "frontend" looks pretty, with different interactive controls and stuff. You can combine the two quite easily (highly recommended) to create something really cool!
1. Debug
So, the first place on this subjective list goes to the Debug library. I previously told you that only the directly-downloaded packages are meant to be included in this list. But, Debug - the package that I really haven't used before - scoring almost double the weekly download count of Commander.js (42M) is just staggering!
As for the module itself - it takes the whole "simplicity" concept to whole another level! It's just a simple debugging utility inspired by Node.js, that allows you to just group your logs for specific modules, and thus toggle the debug output with ease. Of course, there are some styling and tagging involved, but it's not considered the main feature of this package.
import debug from "debug"; import http from "http"; const httpDebug = debug("http"); httpDebug('booting %o', name); http.createServer((req, res) => { httpDebug(`${req.method} ${req.url}`); res.end("hello\n"); }).listen(3000, () => { httpDebug("listening"); });
So, where the 42M score comes from? Well, from libraries and tools like ESLint (6M), Babel (7M), previously mentioned Express (9M), Mocha (2M), Socket.io (2M), and around 28K other dependents. With some quick math, you can easily count up to this impressive 42M.
Comments
Post a Comment
Share your thoughts!