Written by Obinna Ekwuno✏️
Rust is used to build fast, highly scale-able, memory-efficient software. Whether you’re building a CLI tool, web apps for the server or client, network services, embedded systems software or desktop software, Rust is robust enough to cater to all your programming needs.
A framework is typically a combination of tools, helpers, and libraries that provide a way to (quickly and effortlessly) build, test, and run applications. It lays out a foundation for building software. Key aspects to look out for when choosing a framework are its architecture and features (such as support for customization, flexibility, extensibility, security, compatibility with other libraries, etc).
This article aims to showcase several Rust frameworks across different niches, highlighting their strengths and shortcomings. By the end, you should be able to make informed decisions regarding the Rust framework suitable for your needs.
With 8k stars on GitHub, Rocket is one of the most mature, production-ready, full-stack web frameworks. Its major strong point is that it doesn’t make you sacrifice speed for a productive environment and vice-versa like many frameworks do. It helps write fast, secure web applications and doesn’t sacrifice flexibility, usability or type safety.
Other cool things to note include:
- It supports JSON out of the box so you don’t need to have another dependency for that
- Form handling is easy and simple. It doesn’t let bad form requests through so your code doesn’t break. It gives you complete control over all aspects of your application
- It comes with a built-in templating support
- You can view, add, or remove cookies, with or without encryption, without hassle
- It type checks route URLs
- It runs unit tests on your applications with ease using the built-in testing library
- You can configure your application your way for development, staging, and production
My favorite feature is not having to worry about boilerplate code. Rocket makes extensive use of Rust’s code generation tools to provide a clean API, so if you want to build a server-rendered web app, Rocket is a great tool. See more on the super easy-to-understand documentation.
Actix a server-rendered framework. The architecture is based on Rust’s very powerful actor system and touts itself to be a fun web framework to work with. According to this benchmark, Actix is the fastest web framework. It’s well suited for writing services with hard logic and components. You get to also use these services in an async way.
It also provides a lot of features (like logging, http/2, etc.) out of the box. Depending on your preference, it’s boilerplate code could help you get started quickly or be overkill if you’re writing a simple app. It is a great framework with proper documentation. Learn how to get started here. It’s approachable even for the absolute beginner.
It is non-opinionated about how you should write your code which means it does not come with a template or give specific methods of doing things and has a more gradual learning curve. Nickel supports defining templates with mustache.rs, all you need is to create the template.
Nickel makes it easy to map JSON data directly right onto your
struct, and by default, Nickel catches all errors with its default
ErrorHandler and tries to take reasonable actions. So no need to write your own custom errorHandler.
Routes can be as simple as /fizzBuzz, use parameters, wildcards or even double wildcards. Middleware are the extensibility points of Nickel. It comes right out of the box with existing Middleware which you can extend should you wish to. The getting started guide can help you right away.
- Reusable component architecture
- Another cool feature is services. They allow for the reuse of the same logic across components. These services are stateless. It makes use of the concept of agents which is also used to share data across components and provide an overall state for your application
- It uses the WebWorkers API to spawn agents in separate threads and uses a local scheduler attached to a thread for concurrent tasks. This enables high concurrency applications within the browser written in Rust
Some of the cons include:
- Testing isn’t completely wholesome in yew. Yes, you can test individual services but there is no way, as of yet, to test components or agents. Both integration and end-to-end testing can’t be accomplished in plain Rust at the time of this writing
- Yew seems to be in its early stages and as such, there isn’t a proper official guide on how to use it
- Cross-platform GUI toolkit (Windows, Linux, Mac)
- Immediate-mode API, widgets are composed via function composition
- CSS styling engine, flexbox-based layout
- Built-in controls for common user interface elements
- Create custom widgets via function composition
- SVG rendering engine, 2D drawing helpers
- OpenGL integration
- Async I/O helper functions
- XML serialization and hot-reload, built-in XML-to-Rust compiler
- Single deployment binary, minimal binary size (roughly 5MB all-incl.), CPU (0 – 4%) and RAM usage (~ 50MB total)
- Hardware-accelerated OpenGL rendering (0.5 – 4ms)
- React-like DOM diffing for incremental layout and styling changes
- It doesn’t possess an extensive community and it’s still in early stages. It is production ready nonetheless.
Get started here.
Conrod is a portable, 2D, GUI library for Rust. It provides an immediate-mode API that wraps a retained-mode widget state graph, allowing for the exposure of a simple, robust and reactive interface while approaching the performance of traditional, retained GUI frameworks.
Intermediate-mode refers to a style of user interface API, where GUI widgets are instantiated using functions in an update or draw loop which is quite different from the more traditional “retained mode”, where widget types are constructed during the setup stage.
- An easy to use style for highly dynamic interfaces and those that require frequent synchronization with application state
- Highly performant
- It, however, needs lots of stabilization and in my opinion, isn’t a completely robust framework as of yet but shows a lot of promise mainly due to its immediate-mode API approach
Get started here.
Based on Qt which is a very mature cross-platform user interface library. There exists a wrapper for most languages out there and of course, Rust isn’t going to be an exception.
It enjoys all the immense benefit of Qt and of course the small binary sizes which is a trademark feature of rust. These features include:
- Development allows porting an application to multiple platforms through simple recompilation
- It increases development productivity and decreases time to market, making applications future-proof
- Developing with Qt simplifies technology strategy and, ultimately, reduces costs
- Saves time, through one code deployed across all screens and platforms
- Coding in Rust gives the developer greater control and the possibility to work with numerous existing libraries
- The code is compiled to native binaries that run at full speed (no need to use a virtual machine)
- Its cross-platform software development makes it easy to create intuitive experiences for all users, no matter what system is used
- It inherently suffers the same downsides that come with Qt like the QObject and QWidget not being thread-safe
- User Experience (UX) is far from being smooth. On desktop platforms, it is easier to develop native user experience because there are more common patterns and widgets, meanwhile, mobile UX is different and there is a lack of platform-specific things
- When using QT GUI components by default, you do not get an ideal look and feel of iOS and Android
With Qt being a proven framework for cross-platform app development being supercharged with Rust makes this framework formidable and probably the most mature GUI Rust framework. You won’t have to worry about huge builds and interface complexity since the Rust Qt Binding Generator was rewritten in Rust and now available as a cargo crate. This makes development in the common case significantly simpler.
As a low-level language, Rust is perfectly suitable for making user interfaces the old fashioned way, with native APIs. Sadly, in today’s world, which typically involves supporting many platforms, using native APIs is an unattractive option for many.
However, Rust’s expressiveness and high-level abstractions make it ideal for building intricate and complex user interfaces. Unfortunately, there is little consensus on what the best abstractions are especially with the uniqueness of the web. Use what works for your use case and iterate as the need arises.
There are many more Rust based web and GUI frameworks that are in their infancy like core foundation, druid, Iced, relm, and web renderer to mention a few. You can check them out, contribute or even spin up your own framework. Happy coding 😀.
Editor's note: Seeing something wrong with this post? You can find the correct version here.
Plug: LogRocket, a DVR for web apps
LogRocket is a frontend logging tool that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.
Try it for free.
Single Responsibility Principle (or SRP) is one of the most important concepts in software development. The main idea of this concept is: all pieces of software must have only a single responsibility.