Have your cake and eat it too … a post about how a fast feedback loop enables startups (or agile teams) to deliver the best value to customers.
We started working on Cribl LogStream almost exactly 1 year ago (early July 2018). In this time frame, we’ve managed to GA (Oct 2018) and release 6 more feature updates. Speed and quality are key to the survival of any startup. We’ll focus primarily on speed in this post, which is quite different than performance.
Why change? There are two key disadvantages when taking a runtime as a dependency:
- your customers need to adopt that runtime and
- you need to support multiple versions.
Contrary to engineers’ belief, not everyone updates to the latest version 🙂 and enterprises have more speed bumps to upgrades, remember that there are now two things to upgrade.
We’re seeing early signs of both of those disadvantages on a few of our customers, and any product area that slows down adoption becomes a prime candidate for being rethought and redone. This time, it is our packaging. What can we do to remove the runtime dependency? The options fall into the rewrite or repackage category – with rewrite failing the speed test. In repackage, the key concept is simply: instead of relying on the customer to provide and maintain the runtime our application depends on, we ship the runtime as part of the application.
It turns out that we could do better than just shipping
node (our runtime) as part of Cribl LogStream. NodeJS and V8 are extremely friendly to “embedders” – applications that want to use them as just a component – tons of popular desktop applications do just that, Slack being a very popular one (using electron). NodeJS has the ability to bundle an application into the
node binary, at compile time, effectively overriding the default behavior when running
node. Thus, we can bundle our application into the NodeJS binary, compile it for all the platforms we need to support and voila, now we have a native binary with no other dependencies! In languages that compile down to native code, this is known as statically linked applications.
With this solution we get both benefits of building using a language that allows us to move fast and minimize customer adoption friction.
As part of this effort we are open sourcing a tool js2bin, that we’ve built to help us with the packaging of Cribl LogStream on multiple platforms.
Aren’t there any other tools out there that could do this (why build)? Before embarking on building js2bin we considered 2 other utilities for packing NodeJS applications into a single binary: pkg and nexe, but decided against using either for the following reasons:
- They both embed users application and other content by appending to the executable – while this method works, it can also trip malware scanners as the executable contains extraneous content.
- They non-trivially patch (see here or here) NodeJS source or it’s build tool chain which we believe leads to a brittle solution
- They both try to do a lot more than just embed your application into a native executable, they can pack other data files thus need to provide a virtual filesystem and modify your code while embedding. This goes contrary to our belief of doing something well defined very well.
When creating something new, almost all decisions are made using incomplete information. As such, it is your responsibility to actively observe, analyze and adapt as new information becomes available. If you’ve made it this far, we’re hiring! Drop us a line at firstname.lastname@example.org