Tom MacWright

tom@macwright.com

Shiny stuff in the pipeline

Skateboard

Change is hard, and often controversial. Especially in the realm of web technology, the pace of change makes everyone occasionally feel overwhelmed, like they’re slipping behind. It’s tempting to assume a conservative or reactionary position, assuming that new complexity is ‘for its own sake’.

But I’m optimistic about the evolution of the web, and am watching a lot of early-stage changes with anticipation. Here are some of them.

The pipeline operator

The pipeline operator is cool because it could create peace between functional programming and fluent interfaces. Take date libraries for example. There’s the hugely-popular moment, which has an interface like

moment().startOf('day').fromNow();

And then there’s the newer, hipper date-fns, which would express the same as

formatDistance(startOfDay(new Date()));

moment’s interface will feel familiar to folks who’ve used jQuery or d3 in the past - you call methods on an object and it keeps returning this (itself) so you can keep chaining those method calls.

In my opinion, this is a classic situation where sometimes you want to write code one way, and other times it works better the other. With current libraries, that’s just not possible – you write a library to work with the fluent style or with the functional style.

The pipeline operator could fix all of this: you could write modules in the functional style and then call them fluently. For example, if the pipeline operator landed, then you could write this with date-fns:

new Date() |> startOfDay |> formatDistance

And they could this without changing date-fns at all.

The pipeline operator will be familiar to folks who have used Elm or Clojure. When I’ve worked in those languages, it has really shined, and I’d love for this API design question to be finally answered in a way that makes it easier for package maintainers to make everyone happy.

Class properties and ES Modules

If you’ve been writing modern JavaScript, there’s a good chance you’ve already started using these things. Many React projects use class properties to keep the value of this correct when a React.Component method is called from an event handler. And lots of projects web-wide use ES Modules through tools like Webpack and Rollup, which bundle together a project-wide set of modules into one production file.

But today you need to use something like Babel to transpile class properties so that they work in shipping browsers, and you need a tool like Rollup, Webpack, or Parcel to transform ES Modules into a bundle.

The day when you don’t need these tools is soon approaching, and it’s pretty exciting. Imagine a development process that didn’t rely on bundlers. And then when it comes time to deploy, you don’t have to rely as heavily on sourcemaps to debug errors, because the deployed code is so similar to the source.

Then, once dynamic import() lands in enough browsers, code splitting can rely on a standardized and simple technique, rather than the kludge of a module-loader that webpack hardcodes into bundles today.

The read/write files API

This is the most controversial of the bunch: it’s a proposal that would add a new API allowing browsers to request access to read & write files on people’s computers. It’s rightfully a discussion, because a naïve implementation could be a security trap and allow web applications to, perhaps, read arbitrary files. But the writers are well-aware of the risks and are being very thoughtful in the design.

This feature would be a boon to nearly every project I’ve worked on - for example, iD could more easily work with XML and JSON files to enable offline editing of OpenStreetMap. Observable could save and open notebooks locally. Mapbox Studio could interoperate better with people’s local SVG files.

Perhaps at some point in the web’s evolution, the concept of local files on disk could’ve gone away, but that didn’t happen. People still use local files, even if they’re on a Chromebook, and the inability of web apps to easily read & write those files is one reason why people continue to use Electron and other web-on-desktop technologies that bring their own complexities and downsides - like, for example, separate WebKit/Chrome instances per app.

BigInt

let biggerThanEverBefore = 90071992547409926700n;

I’ve been using this one already: BigInt is a proposal to add arbitary-precision integers to JavaScript.

There are many rants about numbers in JavaScript, a fair number of which accidentally apply to every language that uses IEEE floating point numbers. But one of those critiques that does sting is that JavaScript only has 53 bits of precision for integers, because all numbers are stored as floating point.

This doesn’t often crop up as a real problem, but when it does the workarounds are pretty brutal – libraries like big.js are available but rob you of all built-in syntax (you can’t use +, -, /, and other operators), and always incur some performance hit. Personally, I run into integer precision issues when trying to solve Project Euler questions, but there are less pedantic cases. For example, indexing systems like Google S2 rely on 64-bit integers as their basic abstraction, and parsing a variety of files into JavaScript yield integer overflows. CSVs, for example, set no limit on the maximum size of a number.

The BigInt proposal adds 64 bit integers and beyond - you deal with arbitrarily large integers, as long as you declare them with a particular syntax, which requires you to append n at the end of each number.


These are all proposals. Web standards can succeed for fail at nearly any time, and some of these are very early. Read/write files, for example, is at a very early stage. It might not happen. Same with the pipeline operator. BigInt will probably get implemented everywhere, because it’s already shipped in Chrome, but it might change a little before Firefox supports it. Class properties are getting there, and same with ES Modules. ES Modules have trod the rockiest road of all, with plenty of surprise changes.