lona-101 Created with Sketch.

Building with Lona, 101

December 04, 2018

In this post, I'm going to outline the process of building my new app, SourceNote, using Lona.

SourceNote is a very small app written for a single platform by a single developer, so it's far from the intended use case for Lona. In other words, I'm going to keep this post short. But I plan to go into more detail about Lona in the hopefully-not-too-distant future — there are a few much more interesting apps and websites (i.e. with millions of users) that are pretty close to shipping some Lona-generated components to production.

What is Lona?

Lona is a tool for building and maintaining cross-platform design systems at scale. It comes in 2 parts:

  • Lona Studio, a Mac app for defining UI components and tokens (constants used throughout the system)
  • Lona Compiler, a command-line tool for generating cross-platform code from the components and tokens

The goal is to design a component once, fully specifying how it behaves in every condition (responsive screen sizes, error states, different languages, etc) and generate an identical UI on every platform you support.

I started the project while at Airbnb, in order to address issues that arose when scaling the design system to hundreds of designers and engineers. It's open source and MIT licensed.

So why use Lona for such a small app?

The whole premise of Lona was to make design systems scalable at large organizations. But... it turns out that the size of the app doesn't really matter.

Building UI components visually is simply better than coding them manually:

  • For macOS alone, it would probably take me 5-10x as long to code the same thing that I can design in Lona
  • The time it takes to build the UI is predictable — there are no weird UI quirks involving hours of stackoverflowing, since the knowledge to solve these is embedded in the Lona compiler
  • The generated code is perfectly consistent
  • It's often more performant than what I would write myself
  • It looks exactly as I intended
  • I can make UI updates in seconds

Also, while Lona is intended for building components used in many places throughout an app, it works just as well for building components or screens used only once. Landing screens and onboarding screens often need a lot of iteration to get just right, and building them in Lona really speeds up that iteration cycle.

Let's take a look

Here are a couple examples of components built in Lona.

Welcome.component

If you've downloaded SourceNote, this component should look familiar. This is the very first screen when you launch the app:

Welcome component

And here's how it looked in Lona Studio when I was designing it:

Welcome component in Lona

Lona made it super easy to lay out the different text and image elements. It was easy to iterate on this screen as I watched beta testers launch the app and run into issues.

ColoredButton.component

The built-in Mac buttons are a little boring, so I decided to make something in a similar style but with a bit more color:

Colored button in Lona

You can see the button has two possible colors. Setting the highlight parameter will cause it to use the green color. I also made sure it looked acceptable if the text ever wrapped around.

ActivateLicense.component

This modal overlay is part of the license activation flow:

Activate license

You can see it uses the ColoredButton component in two places. The text input field is an existing macOS system component (NSTextField), so the one you see in Lona Studio is actually a placeholder:

Activate license in Lona

In Lona, if you want to use an existing component, you can specify its name and parameters, and provide a placeholder UI for Lona Studio to show. Think of this as a contract between Lona and the target app. As long as both sides adhere to the contract, they can integrate seamlessly. If one side doesn't, you'll get a compile-time error. There are other ways to integrate existing components, but so far I've found that this is the most common way.

In this example, you can also see this component has 2 states: default and error. Lona makes it convenient to see both at the same time.

Using Lona effectively

It's important to think through which components should and shouldn't be built with Lona. It's relatively easy to mix-and-match Lona-generated components and hand-written components, so if Lona doesn't have the right features for a specific component, or even if you just don't think it'll be a time-saver, it's totally fine to build a component by hand.

When to use Lona

Good candidates for Lona are components that may be complex visually, but have relatively simple interactions.

The welcome screen and license activation screen are both great examples, since they contain several different components within them that need to be arranged correctly.

Click and hover states are also generally pretty easy to do, so custom buttons are another great example. If I were trying to use the exact native button style, then I probably would just use the native button directly instead though.

When not to use Lona

Components that are very platform-specific should be used directly. It's probably a bad idea to recreate a text input field from scratch, since it's never going to be as polished/fully-featured/accessible as the native system one, NSTextField. Platform-specific components like these should instead be used within larger Lona components, which can then arrange and configure them as needed. The is how the ActivateLicense.component works — I use the system's text input fields, but I arrange and configure them in a larger Lona component.

Additionally in SourceNote, the text editor and note list didn't make sense to create in Lona. Text editors are extraordinarily complicated, so I used an open source component called Scintilla. The note list needed a variety of custom interactions, so it wouldn't have saved me any time to make it in Lona. However, I did make the individual rows in the note list using Lona:

Note list item in Lona

Most of the rest of the components were built using Lona.

What's the workflow?

I usually start a new project with a pencil and a stack of post-its. After that I'll pop open Sketch and come up with a couple more detailed designs for how it might look. From there, I build the designs using Lona, but this time with much more rigor. I have to figure out exactly how the app should be broken down into components, and define how each component should behave with different input parameters and on different screen sizes. After this, I generate the UI code using the Lona compiler and start integrating it into my app.

If I want to make a major design change, I'll head back to Sketch for a bit. Sketch is really fast and I enjoy playing around with different ideas before honing in on my favorite. I focus on getting the main UI flow down, without spending too much time tweaking things to look just right. The UI always looks a little different in the real app, so I prefer to tweak font sizes and paddings when I can see them live. For this reason, I use Lona for adjusting the visuals by a few pixels here and there, testing in the real app as I go.

Is Lona ready?

If you don't mind using bleeding edge software, Lona works fairly well. Today Lona supports iOS, macOS, React DOM, and React Native, so if you're working on one or more of these platforms, I think you can build a good portion of your app's components in Lona. However, it requires a decent amount of effort upfront to learn the tool, and you'll also likely run into bugs and missing features.

So, it's a tradeoff between the amount of value the tool will bring you, versus the effort needed to overcome its current shortcomings. I think it can be worth adopting now for a lot of teams, since there really isn't any better alternative for building scalable, cross-platform design systems. Also, there's very little cost to trying Lona for a few components, and then deciding later not to use it. The generated components are just regular Swift/JavaScript components, so you can stop using Lona at any point. If you're interested in using Lona on your team and would like a little guidance, or if you're just curious to learn more, tweet or DM me at https://twitter.com/dvnabbott.

Want to learn more about Lona?

  • The most thorough explanation is in the README on GitHub: Lona
  • My talk at React Europe outlines some of the philosophy behind Lona. The talk is fairly React-focused, since it was a React conference after all.