Skip to content

Why Napa.js

Daiyi Peng edited this page Aug 7, 2017 · 11 revisions

On July 17, 2007, as a corollary to Tim Berners-Lee's Rule of Least Power, Atwood proposed Atwood's Law which states that "Any application that can be written in JavaScript, will eventually be written in JavaScript."

This prophecy is being fullfilled by Node.js, its vast module eco-system on NPM, and more projects like Angular.js, React, and etc. in the following years. "What JavaScript can do" leads to "what JavaScript will eventually do".

As we studied backend services in Bing, many of them were computational and implemented in pure C++, for performance. Yet they evolve quickly, while algorithms were added, modified and removed every week in Bing's serving stack. If we can find a way to accommodate both performance and agility, it will be a game changing story. We surveyed a few dynamic languages, JavaScript stood out, thanks to the blazing performance that V8 JavaScript Engine had brought us, and a large JavaScript module eco-system on NPM.

We have four key requirements to satisfy: 1) the solution should provide mechanism to quickly iterate on the algorithm; 2) the solution should take advantage of multiple cores; 3) across multiple workers they can share memory with structures, and 4) fine granularity parallelism should be possible, that we need to minimize communication cost between threads.

At the time, there were 2 established ways to support CPU bound tasks in Node: Computational code in C++ exposed as async JavaScript function, or Node cluster. The former cannot satisfy requirement #1, and the latter cannot satisfy #3.

So we started Napa.js, with learning and inspiration from Node. We were convinced that multi-thread programming model in JavaScript is essential, that could enable developers to have a dynamic balance between JavaScript and C++ at an arbitrary ratio. For even performance critical projects, developers can start everything in JavaScript, iterate, converge, and gradually convert logics into C++ when things are final. With the non-surprising 80/20 rule applied here, that less than 20% lines of code impact 80% of its performance, we may end up with a happy ending: a mix of JavaScript and C++, with most frequently changing parts (like flow) in JavaScript, and highly reusable, performance critical code in C++, that deliver close-to-native performance service. This programming model can support virtually any service that is written in C++ today.