Marble.js 2.0 🔥 — reactive, better, functional, stronger

Over the past few months, we’ve been working really hard on the next generation of Marble.js—functional reactive HTTP framework built on top of Node.js platform, TypeScript and RxJS. Today we are thrilled to announce the second major release and all the exciting features that come with it. Without undue delay let’s go briefly through the main important things that the newest release introduces 🚀

As we promised last year, version 2.0 brings the feature that probably everyone wanted to have from the very, very beginning — the WebSockets! The bidirectional event nature of the protocol fits perfectly to the reactive environment of Marble.js and for sure will show its sharp claws in the field. 💪

The web is constantly moving forward, that’s why we didn't want to support old technologies, even in favor of their popularity. The new @marblejs/websockets module implements the RFC 6455 WebSocket protocol, which means that by design it is not compatible with Socket.io and any other non-standard WS implementations.

From version to version, Marbletakes even bigger steps in being a functional reactive framework. Besides the monadic flavor of Effect streams, we try to incorporate more and more functional patterns and concepts which can fit well in the framework ecosystem. Version 2.0 brings an experimental, type safe, pipeable API for building HTTP routes that can be optionally used in place of EffectFactory.

But the fancy pipeable API is not the only one functional sugar that we introduced with the newest release…

Dependency Injection is a very simple concept, which can be implemented in many different ways. With the introduction of WebSockets we wanted to have a mechanism where the developer would be able to inject the already running WebSocket server and many other app components on demand. Based on that need Marble.js comes to the DI concept in a different, more functional way, that can be very similar to other popular pure functional implementations. From version 2.0, Marble.js introduces a Context —an abstraction over Reader monad.

Together with Context mechanism, we introduce a new way for bootstrapping servers which makes Marble.js even more extendable than previously.

The Node.js server after startup can emit a variety of different events that the app can listen to, eg. upgrade, listening, etc. As you know, streams are the main building block of Marble.js. @marblejs/corecreateServer allows you to hook your stream to emitted server events.

One of the main goals that we set for the second major release was to increase the type safety and improve the data type inference. Besides the improved way of how the piped data type is inferred inside Effects, the newest release introduces brand new @marblejs/middleware-io package which is deeply integrated with a nifty gcantiio-ts library. Thanks to that, we can validate and check at runtime that incoming data has the shape that you would expect. This powerful library can even extract a static type from the validator that is guaranteed to match any values that pass validation.

Body parsing middleware is even more powerful than before. The previous implementation was very basic, limited and it was almost impossible to define custom parsers for given Content-Types. The second release introduces revamped implementation with extendable API which makes a possibility for chaining multiple parsers together.

As you probably know, it is hard to build a framework or big library that preserves the backward compatibility from the very first iterations. We still learn from release to release and want to deliver the best developer experience as possible without unnecessary breaking changes. But sometimes it is not possible.

If you are new to Marble, starting with 2.x is easy-peasy. The biggest question for current 1.x users though, is how to migrate to the new version. You can ask, how many of the API has changed? Just relax — about 90% of the API is the same and the core concepts haven’t changed. 👌

👉 For current Marble.js users, we’ve prepared a detailed Migration Guide that describes all the breaking changes that can be relevant during the migration process.

Marble.js documentation was always very important, even from the very beginning. We’re always working hard to improve it even if the grammar is not always perfect. 🙈 The release 2.0, brings restructured docs with dedicated chapters for HTTP and WebSocket topics. Together with that, we introduced a dedicated “Advanced” chapter, where you will be able to find out more detailed and complex use cases. Keep an eye on that! We foresee to bring up more topics there.

We would like to deliver tons of more features in the next major release, but as you know that it is not so simple. Version 2.0 defined strong foundations that we can build new cool things upon. From version to version the framework tries to be even more functional and for sure that is the main direction that we would like to focus on in the releases. Besides that, we would like to take a look at HTTP/2 protocol and improve the developer testing experience.