In response to the call for blogs about the vision for Rust for 2020, I’m going to write about GUI. I believe the time is right for a native GUI toolkit written in Rust, and that such a thing would fill a very important niche. There is a demand for performance (which, to me, includes startup time, RAM footprint, and binary size), and Rust is in the best position to deliver on that.
I’ve been interested in writing GUI applications in Rust for a very long time. I started xi-editor 3.5 years ago, under the assumption that it wouldn’t be practical to write the GUI layers in Rust, but that interprocess RPC would be a reasonable way to glue a “core” to GUI front-ends. My explorations have led me to question both assumptions: RPC adds a lot of system complexity, and I also believe that we can write the GUI in Rust. In fact, the druid repo has a Git history that’s evolved directly from an experimental Windows front-end for xi-editor.
We don’t yet know what to build
There are many opinions on the best way to write GUI code, and Rust adds its own complications. Rust makes certain idioms easy, but does not adapt well to the traditional object oriented model of the world, which at heart is a big wad of shared mutable state, where interacting objects all have references to each other.
Even within the object-oriented world, there’s nothing like a consensus, though there are many successful examples. The trend is moving from classical OO approaches (including various permutations of model and view, as explained in the Model-View-Catharsis essay) to a more reactive approach, which is more declarative. But there is great diversity among reactive approaches as well, including pure Functional Reactive Programming, The Elm Architecture, which is no longer based on FRP, and various other adaptations. (Yaron Minsky’s Breaking down FRP is a good overview of theoretical approaches, while Dan Abramov’s React as a UI Runtime is an excellent dive into React, including the motivation for its newer emphasis on Hooks).
Even these two major categories don’t quite cover the space. In game circles, various forms of immediate mode GUI are popular, as they promise a more declarative UI style and cut through a lot of complexity. The best example is Dear ImGui.
A major new inspiration is SwiftUI, which takes inspiration from reactive approaches, but is its own thing. It relies heavily on support from the Swift language such as property wrappers, which to me come across as “magic.” I’d also like to mention Lager, which has some similarity of goals with SwiftUI, but is based on C++, and relies much more heavily on immutable data structures (likely a better fit for Rust than the reference-heavy Bindings and such of SwiftUI).
At a lower level, there is almost as much diversity of opinion about rendering technologies. Should rendering be based on the traditional 2D graphics model, or expressed more in GPU-centric concepts. To what extent should it adopt technology from the Web, such as the use of CSS to describe styles?
Basically, all of the above choices can lead to working GUI. But some choices will yield better results at lower cost, while others will be plagued by tedious, errorprone code, pernicious performance problems, or difficulty expressing that ever so important final bit of UX polish. A big company could throw a dart and pick an architecture, pouring in resources until it was good enough, but to be viable as community-driven GUI we have to make smarter choices. And the best basis for those choices is to try a bunch of things and see what works. I believe druid is a credible choice, and to the extent that it fails, those failures will be interesting to the broader Rust GUI effort.
This thinking drives the roadmap for druid itself. For the next few months at least, the primary focus is building a single app: Runebender, a font editor. Since building a GUI toolkit is such an ambitious effort, deliberately reducing scope is one way to get a better chance of success. Of course, I don’t want to discourage experimentation, but the message should be clear: the closer your app’s needs are to Runebender’s, the better chance druid will meet those needs any time soon.
Runebender is generously supported financially by Google Fonts, for which I am very grateful, as it makes it more of a serious and professional project. It is still very early days for the functionality of the app, but I am hopeful it will grow into a productive and creative tool (and I plan to spend a fair amount of time in it as a user, creating new fonts). The funding covers one other full timer, Colin Rofls, who’s doing the bulk of the implementation on Runebender and a ton on druid as well. We’ve been working together a long time, as he’s also been one of the main people on xi-editor.
I agree with hwc’s post that we need to focus on community, and feel it’s particularly important for nurturing a viable GUI toolkit. Here are some thoughts on that.
First, use a general positive tone of support. I think this has been characteristic of the Rust community, but I want to emphasize it. Because we don’t know quite what to build, all of the Rust GUI efforts can provide valuable lessons. The projects should try to learn from each other and share common infrastructure when possible. Criticism should be constructive and not be based in simply different opinions or tastes, or in impatience. Building a true Rust GUI is an ambitious, multi-year effort. None of the Rust GUI crates are good enough to use for production now, but hopefully in time we will get there.
Second, find good discussion forums. I value /r/rust as a common gathering ground for the Rust community, but am less impressed with it as a place to share deeper knowledge or facilitate decision making. It’s definitely one of the best subreddits, and Reddit is definitely one of the best chan-style discussion boards, but I still aspire to something better, or at least better suited to the actual needs of open source projects. (For a top-notch exploration into those needs, see Evan Czaplicki’s The Hard Parts of Open Source.) Not being satisfied with any of the existing discussion spaces is one reason I started the xi Zulip. That is the community space for druid, apps we’re building in druid, and infrastructure. People working on other GUI toolkits are welcome there, and I think there’s scope for interesting discussions and tending of common resources. In addition, blogs continue to be the best place for longer-form explorations of deeper topics. I’ve not been writing as much here as part of a deliberate attempt to manage my priorities and energy, but in 2020 I plan to make explicit space for it.
Third, don’t forget the value of in-person interactions. It’s easy to imagine that all important business takes place on the Internet, but that’s not true. I’m fortunate to be in the Bay Area, and have been enjoying Rust meetups as well as regular coffee dates with Rust people here. Also conferences and my trip to Europe, where I spent some time with (among others) Rik Arends, creator of makepad. These meetings are more important to my understanding of what’s going on in Rust GUI space than online interactions.
Fourth, there’s a lot of scope to expand on existing efforts like areweguiyet. Sadly, the incentives of the modern Internet don’t support such journalistic efforts well. But there’s so much more that could be done here, including comparisons and progress reports on the various GUI efforts, performance evaluation of different rendering approaches, etc. I personally plan to write about such topics, but of course advocating druid. Having a neutral, well-informed perspective would be an amazing resource for the community, and I am sad there is not more of this sort of thing.
Fifth, seek out mentoring relationships, both as mentor and mentee. Jane Lusby gave a talk on Navigating The Rust OSS Community, emphasizing the importance of mentoring. A significant fraction of my workweek is mentoring people in the various projects related to Runebender and druid. Also, we’ve done (as the xi organization) Google Summer of Code the last two years, and hope to scale that back up in 2020. If you’re a student who’s a candidate for GSoC, now’s not a bad time to start planning.
I’m consciously trying to grow druid as a community effort, and so far the results have been very encouraging. The Linux port (now merged to master!) was done by a team of contributors (Steven Van Bael, Andrea Cognolato, and Rasmus Thomsen), and much of the work on individual widgets is now being done by the community as well, thanks in part to a recent tutorial by Paul Miller. As of now, there are a total of 25 contributors, and I want to thank all of them for their work.
Rust language support
For the most part, this vision doesn’t really depend on much from the Rust language. Of course, when developing GUI, iteration cycles are important, so improvements in compile time are also welcome. Better support for hot-reloading is likely to pay off as well. Web is one of the targets for GUI (very experimental still in druid), so building out the wasm infrastructure is also great.
But generally this is about libraries and ecosystem, not the language or the compiler. It is an open question whether the Rust community can sustain an effort as ambitious as building a GUI toolkit. I hope and believe it can, and am happy to be a significant part of my time and energy in 2020 trying to make that happen.
Discuss on /r/reddit.