Progress: software packaging dependency & abstraction, a tradeoff worth taking

This is a guest post for the Computer Weekly Developer Network written by Burke Holland in his capacity as director of developer relations at Progress — the firm is a specialist in backend application build tools, PaaS technologies and (now with the acquired Telerik) it also offers tools for building the interface on the front end.

Holland writes as follows…

While the concept of packages in software is as old as software itself, there has been a turn towards ‘micro packages’ in the past two years. These micro packages are libraries that are miniscule in scope, some containing only one line of code.

They are rising in popularity due to the widespread adoption of a centralised package repository; in this case, the Node.js package manager or (NPM). Built on Google’s V8 open source JavaScript engine, Node.js enables developers to create server side applications using JavaScript – the great code equaliser.  

NPM works with Node.js and JavaScript to make it easy for JavaScript developers to share and reuse code.

Too many packaging systems

In the past, every language and platform had its own packaging system. Ruby with gems, .NET with Nuget, Java with Maven and so forth, making it impossible for developers to truly share all of their code. Not so with JavaScript, quite easily the most popular and widely used programming language in history.

Combine the rise of more server side and front end JavaScript applications and we are now able to truly scope our packages as finely as a developer requires. Node.js package manager (NPM) encourages this with its seamless integration to Github and the virtually non-existent barrier to publishing a package.

Even Microsoft has built NPM support into its tooling. Packages on NPM vary in capability. Some are enormous in feature and scope, such as NativeScript, which is an entire runtime for building mobile apps. While it doesn’t ultimately run on Node, the tooling is built via NPM.

Another example is the Angular CLI which pulls down 966 NPM libraries just to build an Angular application.

Package abstraction

NPM has done such a remarkable job of package abstraction, making applications more modular than ever before, even if nobody has realised it. Such ease in package management doesn’t come without trade-offs though. When developers use NPM packages they are taking a dependency on them, meaning that if the creator decides to remove their package, this could cause some problems.

This was seen with the LeftPad scandle of 2015. The developer unpublished a module that did nothing but pad using a specific number of arguments. However, this package was used everywhere and as a dependency in other popular libraries such as Babel. While this won’t ever break a production build, it did cause widespread consternation by developers trying to setup new projects with a non- existent LeftPad dependency.

Taking the dependency tradeoff

Taking dependencies is itself a tradeoff – a developer sacrifices control for productivity. However, it’s a tradeoff worth making.

Productivity is the lynch pin around which a developers’ success revolves. In order to solve common problems (making an AJAX call, handling a server request, left-padding a string), developers use already published solutions that can be found in NPM.

When other developers need the same functionality, instead of having to write and test it, they can simply include a package which has already been written and tested. This ensures that they don’t have to reinvent the wheel every day.