The Typelevel stack and Scala Native

Key points:

  1. The Typelevel stack now offers a complete platform for Scala Native: concurrent fiber runtime, non-blocking network I/O, TLS, HTTP server+client, Redis client. Coming soon: Postgres client, serverless integration, server/client code-generators. It is now more viable than ever to build production applications on Scala Native.
  2. The success of (1) is thanks to years of hard work and demonstrates exactly how far Scala Native has come. But the project is also facing some immediate challenges, such as maintaining Scala 3 support, that may threaten adoption.
  3. Scala Native has a vibrant community working on core, tooling, and libraries. Wojciech Mazur is beyond-words phenomenal, but is the sole maintainer with only a “fraction” of their time available for the project. The current commitment of Virtus Lab and Scala Center to the project is unclear to me.

My questions:

  1. What additional resources can be dedicated to the project, or could be made available in the future?
  2. Specifically, what milestones would stakeholders like to hit to encourage allocation of said resources?
  3. What are the technical next steps for the project to best achieve those milestones?

At the bottom of this post I have included a list of some Typelevel stack libraries that recently cross-compiled for Native or I anticipate will do so soon. I have selected this subset of libraries because I believe they are novel offering on the Scala Native platform that (1) play to its strengths and (2) lower the barrier to adoption.

  1. These libraries are largely designed for building concurrent services with asynchronous, non-blocking I/O. They are not trifled by Scala Native’s single-thread limitation and enable you to serve 1000s of connections simultaneously. This is effectively the Node.js model.

    Furthermore, thanks to native interop, the runtime can be deeply integrated with kernel I/O APIs such as epoll, kqueue, and io_uring. Indeed, the epollcat project mentioned below implements one such runtime. Combined with instant startup of native binaries, I believe there is real potential for an interesting, competitive offering for deploying scalable, I/O-bound services with Scala Native.

  2. With the exception of FS2, which implements non-blocking network I/O and TLS, the libraries listed below cross-compile for Native with virtually no changes to their source code. These are not “Scala Native” libraries, these are bona fide Scala libraries that cross-build for Native with identical implementations, APIs, and semantics to their JVM counterparts. Downstream libraries and even existing applications can cross-build effectively “for free”. I am hopeful this lowers the barrier for adoption.

On the topic of lowering barriers, I think two UX improvements could go a long way towards improving user adoption of Scala Native, for developing applications:

  • Incremental linking, so each tweak/test iteration doesn’t take several minutes :slight_smile:
  • Line numbers in stack traces :slight_smile:

I also touched on my concerns due to Scala Native’s unfortunate entanglement with Scala 3 compatibility. As an OSS maintainer, my biggest fear is that due to these sorts of complications I will have to rip Scala Native support out of a library to avoid compromising JVM development.

These problems are solvable, so long as someone is available to work on them. Which is why I am eager to hear from Virtus Lab and Scala Center about what their goals for the project are and how we can build on the current momentum.

There was some recent discussion in the old “Scala Native Next Steps” thread (when that thread started there were 1.5 engineers on the project!) of which only EPFL’s commitment is clear, at least to me.


Note this is only a very select subset and feature highlight of what’s available on Scala Native :slight_smile: I hope that the new Typelevel offerings are interesting and I look forward to connecting with you in those projects’ channels!

Cats Effect v3.3.14 (1.6k ★)

  • lightweight fiber (aka green threads) runtime
  • userland-extensible event-loop execution context and scheduler

FS2 v3.3.0 (2.1k ★)

  • non-blocking TCP sockets via epollcat
  • TLS support via s2n-tls

http4s v0.23.16 (2.3k ★)

  • Ember, a 100% pure Scala server+client with HTTP/2 support
  • wealth of middlewares and ecosystem of integrations

Rediculous v0.4.1 (34 ★)

  • 100% pure Scala Redis client

In addition, I expect the following libraries to be published for Scala Native in the near future:

Skunk (1.4k ★)

  • 100% pure Scala Postgres client (save some crypto routines)
  • Scala Native PR is already up and CI is green. That test suite is no joke!

smithy4s (192 ★)

  • server/client code generators from Smithy IDL

feral (111 ★)

  • severless framework for AWS Lambda

… and many many others

36 Likes

This is a great achievement, indeed! Kudos, and thanks for doing all that work!

I want to give a light warning that this might sound good in theory but is a big problem in practice if you want to build scalable services. There are some use cases where the single-threaded node.js model is good enough, e.g. if you build stateless services, or services that use external databases for all their state (and use no caching in the heap).

However, modern CPUs have lots of cores and the most energy efficient CPUs have rather more low-power cores. The model that is proposed here would mean that for scalability you would have to create as many server processes as there are cores/threads on a server. For many stateful services, this means, instead of a single node with N CPUs, you have to run an N node cluster on a single machine with all the coordination, serialization, and potential cache duplication overhead that brings.

So, providing proper threading (+memory model) support, really would be an important milestone for scala-native.

4 Likes

Thank you for the reply!

I absolutely 100% agree. My concern is that properly supporting multithreading is an enormous amount of work for a project that is currently very under-resourced, and furthermore that work distracts from less ambitious improvements that will do more to improve adoption today. To quote you from the old thread:

Essentially, I am trying very hard to help carve out that temporary niche. We now have a platform, and I think the ball is in Scala Native’s court again to catch up with UX improvements (such as incremental linking and line-numbered exceptions) as well as performance (early benchmarks of http4s Native show that it’s not atrocious, but there’s still work to be done to match the top Node.js frameworks). This will help make Scala Native a real production choice, not for every use-case as you point out, but at least for some.

Of course, this is predicated on the assumption that Virtus Lab and Scala Center want to see more adoption before they will allocate more resources for the project.

5 Likes

The Typelevel stack now offers a complete platform for Scala Native: concurrent fiber runtime, non-blocking network I/O, TLS, HTTP server+client, Redis client.

I really want to congratulate everyone that made this possible.

Let me clarify VirtusLab commitment to Scala Native: @WojciechMazur’s work is co-financed by EPFL and VirtusLab, allowing him to work full-time on Scala Native. That should be sufficient for active maintenance as well as working on new features with help from the community. Martin is also looking for more people to join the team to further help with Scala Native, among other things.

It is now more viable than ever to build production applications on Scala Native.

If some kind of support subscription could help anyone to start using Scala Native on production, we could extend our offer for Scala 3 and Metals to Scala Native. Of course, in such case, the team would need to be expanded.

Virtus Lab and Scala Center about what their goals for the project are and how we can build on the current momentum

Our (VirtusLab) current goal is to deliver the things that we mentioned in the Scala Native Next Steps thread including support for multithreading and iron out the Scala 3 and Scala Native story before the first LTS version. We are also in the process of building the next roadmap, so we are open to any suggestions.

10 Likes

Thank you! For curious readers, we have just published more of the story on the Typelevel blog.

This is fantastic news! Thank you for confirming your commitment the project. Admiration for Wojciech is widespread and we appreciate Virtus Lab’s ongoing championship of Scala Native. I look forward to continuing to work with him as a community contributor to the project.

5 Likes

Yes, we have the funding to give Scala Native a big push. One problem I have encountered is finding the right people. If you have good compiler and systems programming expertise I’d be happy to see your application. Things we need: Compiler backend experience, Scala, LLVM, C/C++ for the runtime system.

8 Likes

Many if not most services are stateless. Scaling them up can be very easy, for instance with docker swarm or Google Cloud Run. And many people are already using more advanced orchestrators like kubernetes.

I agree that it’s a big limitations for stateful services. But stateful services perhaps have much less of a benefit from going native anyway. They would tend to be long -lived processes, no?

1 Like

Hello,
Unfortunately, the Scala Center is not anymore actively working on Scala Native. It is worth knowing that when it was part of our roadmap, the resources were partially funded by VirtusLab and an individual donator from the community (many thanks to them!). Scala Native has its use cases but it needs more resources to fulfill its great potential. We believe that the Scala Center has a higher impact on the whole community by focusing on the more core activities of the developers (editing programs, compiling, releasing, debugging, managing security vulnerabilities, etc.).

8 Likes

Thank you for the update! Even though the Center is not actively working on Scala Native it is wonderful to know of your support for the project and its potential.

Also, it is important to recognize that the Scala Center’s ongoing work on Scala.js is a significant influence on Scala Native as well. Recent achievements such as the Scala.js Javalib implementation completely independent of the Scala library show the path for long-term sustainability as the Scala Native project matures. So thank you for your continued investment in Scala as a cross-platform language!

8 Likes

It’s can be confusing for the community that there are different groups responsible for different aspects of the overall Scala effort: the Center, LAMP, Lightbend, VirtusLab. Individuals come and go, money comes and goes, and as a result sometimes efforts have to be shifted around. That’s normal, but it’s also understandable that observers can get confused, or even alarmed.

Anyway, thanks for the clarifications from everyone on this.

10 Likes

I want to congratulate Typelevel with this effort. It is amazing to finally have http4s available on Scala native! So, why does Scala Native matter?

  • running services in the cloud does not need multi core setup
  • k8s is more or less a button to click these days in GCP / Azure etc., scales far beyond the jvm
  • lightweight runtime, like a scala native binary running in Docker is way more efficient than using a jvm, the Docker image is faster to build and easier to maintain.
  • In microservices paradigm I would imagine most services are stateless these days
  • If you need state, you would use Redis or similar.

I mostly work outside of the jvm ecosystem these days, it seems to me that the jvm loose more and more traction, because it is not very suitable for containers. Paying license for Graal native is not going to happen for someone using node ecosystem for example, while trying a small microservice with Scala Native would be a very small effort in comparison.

I think this is a great article!

1 Like

I think TL’s Scala Native support is great, but I have to note (having recently come from a Scala-centric, complex, enterprise-scale microservice environment) that none of these is true in my experience:

It’s quite common (more than not, IME) for serious enterprise microservices to have a focused Postgres database behind them, and the JVM runs well in containers…

With stateless I meant that you don’t store any session state in a database in your microservice, you use JWT / auth service etc.

I agree that jvm runs perfectly in a Docker, but it consumes more disk space, memory etc.