The pitch for mruby

Fri Jan 15 12:08:13 2016 Zachary Scott zzak@ruby-lang.org

Hello!!

Probably, nobody knows mruby.. let's change that.

For the last year-ish, I've been working on mruby and spoke at several conferences about it.

MRuby is really important to me, and I believe it will play a big role in the future of Ruby.

In this post we'll learn about what mruby is, where it fits, and why I think it's so important.

But we already have MRI, JRuby, Rubinius, Topaz, etc, etc

Let's assume for a moment that you're already comfortable with your choice of Ruby implementation..

In this case, you probably chose it for a reason:

These are all great reasons, but all of these implementations have something in common:

Packaging is a nightmare and so is portability.

Many of the current Ruby implementations lack decent packaging for standalone applications.

When you look at the history of Ruby application deployment, it usually comes down to packaging the entire interpreter and all dependencies into a fat binary.

This isn't a great solution, and can end up with binaries the size of a small operating system -- not to mention portability is a nightmare since you usually have to package each system independently. This means having a mac mini under your desk for building osx binaries.

Why should I care?

If that sounds like something you care about, allow me to offer some food for thought.

If you answered yes to any of these questions, allow me to introduce you to mruby.

What's an mruby?

MRuby is Yet Another Ruby Implementation, but let's back up for a sec.

As I mentioned earlier, there are many Ruby implementations. All of them are based on Matz Ruby Interpreter (MRI), which is named after Yukihiro Matsumoto (or Matz) the creator of Ruby.

MRI, or CRuby, acts as a reference implementation for all of the other implementations, for better or worse.

However, this isn't the case with MRuby. That's because it's implemented after an International Standard Organization (ISO) specification.

The actual ISO itself is defined from MRI version 1.8.7 but MRuby implements 1.9 compatible syntax, (paraphrasing matz here).

It's still Ruby

You see, MRuby was also designed by Matz to be an embeddable implementation of Ruby. His goal is to put Ruby everywhere, in today's world of the Internet of Things.

What I mean when I say "mruby is still Ruby" is.. it still implements all of the language features that also exist in MRI version 1.9.

So you're free to use lambdas or procs, write elegant Ruby code using blocks and iterators that we all know and love.

As well, you can monkey patch thanks to the same open classes as MRI.

Because it's still Ruby.

From the ground up

That's because matz designed mruby from the ground up after having created Ruby more than 20 years earlier.

When Ruby was originally released, matz was my age.. he was but a padawan learner.

We should give him credit for everything he's experienced in the lifetime of Ruby. It has taught him more about language design and dealing with users demands than most of us ever have.

This means he can apply this experience when developing mruby.

For the last few years, matz has been acting BDFL of Ruby.. However, the mruby project is his love child. He is actively committing bug fixes and merging pull requests.

This means working on mruby is a chance to collaborate with someone of great knowledge of the force.. and languages.

Small at it's core

In order to keep mruby small, much of the standard libraries we use in Ruby are left out of core.

This means File, IO, Socket are all missing from the core libraries of mruby.

Initially the core was designed to implement the ISO specification, but everything outside the ISO is implemented as an extension or library.

Many of the libraries built for mruby are actually written in pure ruby, including some of core. This helps keep the code more maintainable and easier for new contributors.

In addition, keeping a small core written in Ruby helps to keep mruby portable.

This will be a key feature for the success of mruby as we move forward.

A growing ecosystem

Since the release of version 1.0.0, mruby has shipped with a package manager.

This package manager is called mrbgems, and used for integrating libraries into mruby. You can think of it like RubyGems except there is no central server like rubygems.org.

The double-edged sword

One of MRI's strengths is it's rich ecosystem.

Rubygems.org is a wonderful asset to the community, where you can use many libraries to make it easy to build things quickly.

Since mruby is small at it's core, it's nontrivial to port these existing Ruby libraries over. While we can't use RubyGems, this means we're not stuck supporting a legacy system that is hard to change and fix.

RubyGems is a massive codebase with a long history with many hard faught battles. But mrbgems is just a few Rake files and miniscule in comparison.

As an ecosystem we can forge and fix issues that have been long standing in Ruby. For example, building a better story for cross-platform support, including Windows.

We can make it a big part of the ecosystem so that others will follow suit.

State of the ecosystem

For many common use-cases there is a growing ecosystem of already libraries for every day use.

If you need to read a file from disk, parse JSON, or call out over the network: There are already libraries to do this for you.

In order to find these community libraries, we use what's called mgem. This allows you to name a gem as a dependency for your application that will get compiled along with mruby. When compiling your application, mgem dependencies will be searched found under the mgem-list repository.

This mgem-list is very active and growing with new gems every week. Adding a new gem takes just a few minutes, and the community is very welcoming to new libraries.

Our tiny community

As of writing this, there are just under 200 gems in mgem-list. Many of which are written by the mruby contributors team.

The mruby community is still a small, and cozy place to contribute. It's like going into your favorite cafe where you know the owner and patrons.

Everyone is super helpful and excited to be sharing and working together to make mruby a success.

It reminds me of the early days of Ruby, there are no egos.. just people trying to get stuff done.

Who's using mruby?

Even though mruby 1.0.0 was only released 2 years ago, there are many companies already using it in production.

Companies like Heroku, GMO pepabo, and Shopify are shipping projects with mruby. They picked mruby because, like Ruby, it's quick to iterate and get things done.

Internet of Things

In the world of IoT, C is often the first choice for its speed and memory efficiency.

Recently, companies especially in Japan, have started using mruby for it's low-memory footprint. For example booting the REPL of mruby (called mirb, like irb) only takes 660kb of memory.

Since mruby code is usually statically compiled into the final binary, require is not a bottleneck (there is no require in mruby).

When more speed is needed, C is still the first choice in many cases. However, since mruby can be embedded into C, parts of the application code can now be written in Ruby -- except for the main loop.

This allows developers to use Ruby for business logic and data, while relying on good ol' C for the performance.

It really depends on your application, be sure to measure for any bottlenecks that might be better suited for C.

Middleware configuration and Web server extensions

For some, they use mruby to build web server extensions that are commonly written in C.

However, thanks to the ngx_mruby project, they can now be written in Ruby using mruby.

Using ngx_mruby allows developers to avoid writing nginx modules with antiquated C that can be hard to maintain.

We've already seen Heroku do this for their static-site buildpack. Which has been used to develop a middleware routing configuration written in Ruby.

Command-line applications and tooling

Others use mruby to build command-line applications and utilities using mruby-cli.

In production, companies are using it for internal tools to replace unmanagable Bash scripts.

As well, people behind JRuby have started to use it to replace their legacy jruby-launcher project written in C++ and Bash.

With mruby-cli developers can write CLIs in Ruby without the headaches of configuring cross-compile toolchains.

For binaries

It allows developers to create a standalone binary that is easy to deploy and maintain. The default configuration generated for every mruby-cli app is designed to compile 32-bit and 64-bit binaries for Linux, OS X, and Windows.

For testing

During development, mruby-cli supports two ways for testing the application.

First is supported by mruby-mtest, which is a unit-testing library designed to run inside the mruby VM.

Secondly we have bintest, which is designed to run outside the context of mruby using MRI. This allows you to use any of the tools that exist inside the MRI ecosystem for integration testing your application.

For speed

For CLIs, bootspeed is a common concern.

Luckily the "Hello, world!" application in mruby-cli boots in just 0.003 seconds.

In closing

Now that you're familiar with mruby, I hope you give it a try for your next project!

As you can see, there are many interesting use-cases for mruby and I'm excited to see it grow over time.

Please let me know what you think and what you create using mruby!!

If anyone would like to add their company or use-case to this list, I'd be more than happy!