JavaScript in 2017: Year in Review, Predictions for 2018
December 26, 2017
2017 has been a wild year for JavaScript and frontend development. A new version of the language was released, GraphQL was announced, compile-to-JavaScript languages were rolled out by the dozen, React became the default frontend framework, and more. Here’s a rundown of 2017 trends, and my predictions for 2018:
The Rise of Compiled Languages on the Frontend
Language-to-language compilers let you do things like compile JavaScript to TypeScript (I think there will be a lot more interesting work in this space!), TypeScript to Flow, Flow to TypeScript, TypeScript to Reason, SQL to TypeScript, JavaScript to Go, and Go to JavaScript, to mention a few.
On the frontend, TypeScript, Flow, ScalaJS, Elm, ClojureScript, PureScript, Reason, and other compiled-to-JavaScript languages will continue pushing the envelope and introducing frontend programmers to features that make them more productive, and their code safer and easier to maintain. Features like TypeScript and Flow’s dependent type support, Elm’s powerful signal system, and Reason’s pattern matching will continue to win mindshare.
And JavaScript won’t stay the compile target for these languages forever. With WebAssembly, we’re inching toward the dream of isomorphic codebases, where programmers write code in one language and run it on backend, frontend, or wherever else without having to learn the ins and outs of a handful of totally different languages, and without having to give up startup and runtime performance. In the next 2 years we will see WebAssembly becoming a compile target for existing languages, right alongside JavaScript.
2018 Prediction: Compiled languages will become increasingly popular; compiled languages will begin to target WebAssembly instead of JavaScript.
The Triumph of Gradually Typed Languages
Every successful engineering organization goes through the same evolution:
- Build an app in a dynamically typed scripting language so engineers can iterate quickly
- Hire more engineers
- Realize that those engineers can’t iterate quickly anymore because there’s no documentation
- Realize that those engineers are breaking the app because they don’t know what else a change might affect (you probably regret not listening to your coworker when she said “write more tests!” in all of your code reviews)
At this point you face a tough choice: you can start rewriting your app in a statically typed language, or you can keep investing in JavaScript/Python/Ruby and focus more on test coverage and documentation (it’s not an easy decision; different organizations come down on different sides). But once your codebase is big enough, it might no longer feasible to rewrite everything.
Gradual typing to the rescue! TypeScript and Flow for JavaScript, MyPy and PyType for Python, Hack for PHP, RDL for Ruby, and Typed Clojure make scaling dynamic code across more engineers possible. Gradual type systems:
- Are built to interoperate with untyped legacy code
- Are easy for existing engineers to learn (you just have to learn a few annotations, not a whole new language and runtime)
- Give you free documentation
- Cut down on the number of unit tests engineers write
- Approach the same safety guarantees that statically typed languages give you
- Make engineers (especially engineers new to the team) productive again
To ease the migration to static types, people have built some really neat tools to help deduce types for your existing dynamically typed code: for example, see MonkeyType and ReticulatedPython for Python, and any number of tools for JavaScript.
On the frontend, 2018 will be the year that TypeScript and Flow live or die. The biggest issue facing both ecosystems is missing & outdated typings for third party packages. Either a critical mass of programmers will start to ship their libraries with TypeScript or Flow types (one can be compiled to the other), or the languages will suffer slow deaths as users leave because the third party typing story is broken.
Of the gradually typed JavaScripts, TypeScript has close to 10x the downloads that Flow or Closure have, and over 10x the number of typings for third party libraries. If gradually typed JavaScripts catch on in 2018, then TypeScript will be the winner among them.
2018 Prediction: TypeScript’s growth will continue accelerating.
The Rise of Code Generation
Code generation tools are becoming a standard step in the frontend programmer’s toolchain. In the last year people have built lots and lots of tools to make APIs typesafe; you can compile JSON, JSON-Schema, and GraphQL to any language, GraphQL to TypeScript, Thrift to TypeScript, JSON-Schema to TypeScript, TypeScript to JSON-Schema, JSON-Schema to Flow, Flow to JSON-Schema, and Swagger to Flow.
The jury is still out on whether GraphQL will beat REST. GraphQL certainly solves a lot of problems (documentation, schemas, versioning, performance over unreliable networks), but there is a big barrier to adoption (it is not plug and play for many use cases, legacy clients still use REST, many apps have magical REST endpoints that do more than read/write a single resource, etc.). If GraphQL loses, then either JSON-Schema or Thrift will emerge as the winning documentation and schema layer.
I like GraphQL, and I also believe there are lighter weight solutions for the problems it solves: HTTP2’s multiplexing and push for performance, Swagger or JSON-Schema for documentation and schemas, API-level versioning. Switching to GraphQL can be expensive and you don’t have to swap out the whole API layer to get these benefits, which is why I believe we’ll see more teams choose lighter weight solutions over GraphQL.
2018 Prediction: GraphQL adoption will slow, and JSON-Schema adoption will grow.
React will Win, Redux will Lose
React has won the small-medium webapp market, and will continue to make its way into the market for large apps. The intuition is that for most apps, simple and predictable performance and mental models are more important than a framework that covers every possible use case out of the box. Sure, I can build an Angular4/Rx app with IndexedDB storage using CRDTs to sync data between users, but then again I could use React and fetch
to do most of that with a fraction of the cognitive overhead.
While Redux’s simplicity solves a lot of problems, the amount of work it takes to understand it, use it, and make it typesafe is a barrier for many. It sounds nice in theory (“Duh, my state is a fold over a stream of actions”), but in practice, I think programmers will continue to use traditional, Object Oriented models (ala. Backbone/Angular/Ember). Most engineers are not functional programmers, and OO models offer an easier way to think about encapsulation. That said, the flood of Redux variants and plugins will continue and Redux will continue to be popular among the FP crowd.
2018 Prediction: React will continue to dominate other frameworks, and Redux adoption will slow in favor of something that looks more like traditional Object Oriented Models.
JSX will Win
JSX-like syntax is supported by TypeScript, Vue, Elm, and Angular, and even Rust and Scala. I could write a whole essay about why I think JSX succeeded, but to sum it up in a sentence: familiar abstractions win, and typesafe abstractions doubly so.
2018 Prediction: JSX will become the standard templating language for HTML.
Webpack will Continue to be the De Facto Winner for Packaging
Other bundlers will come and go, but Webpack will remain the standard through 2018. People are tired of setting up build pipelines, and Webpack works pretty well for the majority of use cases.
2018 Prediction: Webpack will win.
Code Analysis Tools will Become More Sophisticated
Prepack magically pre-evaluates as much of your JavaScript as it can, and gives you a new, smaller bundle that starts up and runs faster than the original. The intuition is that a lot of code can be evaluated ahead of time: if, for example, your code contains the expression 3 + 4
, you know this will always evaluate to 7
; if you can make that substitution before you run your code, you can shave down the time it takes for your app to start up and improve how fast it runs. This kind of optimization is a no-brainer for most teams.
Rollup and Webpack tree-shake your code, reducing bundle size and improving parsing performance.
ESLint, TSLint, and Prettier make linting and automatic code formatting accessible in a way that Closure Linter, CodePainter, JSBeautifier, JSFMT didn’t. Prettier in particular is a zero-config formatter, and it has some clever rules that codify the unspoken style conventions we use when writing code.
2018 Prediction: Prepack and Prettier will become standard tools in every project.
Closing Thoughts
2018 will be an exciting year for JavaScript. The JavaScript ecosystem will continue to mature with conventions around frameworks and tooling (React, Webpack, Prettier, Prepack), a standard library (Lodash, not mentioned here because it’s so 2012), a templating language (JSX), and a static, gradual type system (TypeScript).
And of course Uber will keep open sourcing everything (maybe then people will stop calling them a taxi company).
Have thoughts? Send me an email.