Back

The Most Popular Alternative UI Libraries

The Most Popular Alternative UI Libraries

React. Vue. Svelte. If you’re doing front end development on the web in 2022, chances are you’ve touched at least one of these libraries, and heard extensively about the other two. They’re all great solutions to the same problem, with slightly different tradeoffs.

But what other alternatives are out there for building modern front end interfaces? In this article, we’ll look into a few of the most promising ones. This won’t be a deep dive in each, but you’ll see enough to nudge you to test out one of them for your next weekend side project.

Solid.js

Solid has built a lot of support the last couple of months, and has been hailed as a great alternative for people already proficient in React. Because - well - it’s pretty similar!

At least they look similar on the surface. Both use JSX, are based around the concept of components and have a unidirectional data flow. Here’s a quick counter component in Solid, for instance:

function Counter(props) {
  const [count, setCount] = createSignal(props.count);
  return (
    <button onClick={() => setCount(count + 1)}>
      The count is {count()}
    </button>
  );
}

See - not too different! However, the similarities end at the surface. Solid.js doesn’t have a Virtual DOM implementation, like React, and uses property proxies to trigger changes to the DOM. And their most selling point - the Rules of Hooks doesn’t apply to their version of them.

One thing that stuck out to me when I first tested Solid out, is that you’re not supposed to think of your components as render functions (like in React), but as constructors that help construct a graph of reactive components and values, triggering changes whenever their dependencies change. Pretty neat!

As I mentioned earlier, Solid might be a new kid on the block, but it has picked up substantial traction lately. Definitely worth checking out!

I started my learning path on their website, and I suggest you do to. They are well-written, and easy to scan through whenever you need them as a reference.

Lit

Lit is not as new as Solid, but has been receiving steady updates and a new major one last fall. It’s based on the web standard Web Components, and is championed in part by Google. Now, this should be good!

Lit is small (about 5kb after minifying and gzipping), and is basically just a small layer on top of the Web Components spec. It works in all modern browsers, and comes with full support for TypeScript out of the box.

Here’s a counter component in Lit:

import {LitElement, html} from "lit";
import {customElement, property} from "lit/decorators.js";

@customElement('my-counter')
class MyCounter extends LitElement {
  @property()
  count: number = 0;

  incrementCount() {
    this.count = this.count + 1;
  }

  render() {
    return html`
      <button @click=${this.incrementCount}>${this.count}</button>
    `;
  }
}

Now, the cool thing with Lit (and web components in general) is that this creates a real world HTML element you can use in a regular HTML file. To render what we just wrote, you can do something as basic as:

<html>
  <body>
    <my-counter />
  </body>
</html>

To me, there’s a certain elegance to this! It’s so close to the platform, you don’t really need anything else on top.

That being said, there’s a bit of syntax and APIs to learn, and web components has gotten quite a bit of criticism throughout the years, so consider that before going all in.

To get started, check out Lit’s official tutorial!

Elm

Elm is a functional language that compiles to JavaScript. It’s also a complete front end framework that works in a similar way to React and Redux. As a matter of fact, Redux took a lot of inspiration from Elm!

Elm is often touted for being easy to learn. As a matter of fact, in the consultancy I work in, we teach lots of new devs Elm every year, and most of them get up and running in very few days.

As I mentioned in the introduction, Elm is a fully functional language. That means, no mutable values, lots of argument passing to pure functions and a sort of wonky syntax (at least when you’re not used to it). Here’s a counter example in Elm:

import Browser
import Html exposing (Html, button, div, h1, p, text)
import Html.Attributes exposing (..)
import Html.Events exposing (onClick)

type alias Model : Int

init : Model
init =
    0

type Message = Increment

update : Message -> Model -> Model
update msg model =
    case msg of
        Increment ->
            model + 1

view : Model -> (Html Msg)
view model =
    div []
        \[ button [ onClick Increment \] [ text String.fromInt model ]
        ]

It’s a lot of code for a small piece of functionality, sure, but it’s definitely easy to follow along. You specify your model, it’s initial value, what actions you can trigger and how that modal would change based on them, and finally you specify what you want to have rendered.

Elm has a really neat compiler that does its best to help you figure out where you goofed up. But even more important, Elm has one of the very nicest communities around. There’s a Slack where you get help at any given time, and there are lots of great resources out there to learn

There are a few downsides to Elm as well. One of the biggest ones is that there hasn’t been a release in about 2 years. Not because people aren’t working on it, but because they’re pretty happy with it as it is. It solves the challenge it set out to solve just like it is, and there aren’t a lot of missing features. However, some movement would be fun to see. The other downside is a downside that comes with functional programming and a single state tree - you have to pass a lot of data around, which can get a bit tedious in large real-world applications.

However, Elm is a hoot to learn, and you’ll definitely become a better programmer for giving it a shot.

Get started at the official Elm website!

Stencil

Stencil is another web component based framework, but does a few things a bit differently than Lit does. It’s based around the more familiar JSX syntax, and it has a slightly smoother API.

Stencil came from the cross-platform native app framework Ionic, but was extracted into its own library after some time.

Its main purpose is for creating reusable component libraries that work in any frontend framework you can think of, but you can build complete apps with it as well. Stencil comes with a really useful CLI tool that helps you set up new projects in no time at all.

Here’s the same counter example as the others in Stencil:

import { Component, State, Listen, h } from '@stencil/core';

@Component({
  tag: 'my-counter'
})

export class MyCounter {
  @State() count: number;

  @Listen('click', { capture: true })
  handleClick() {
    this.count = this.count + 1;
  }

  render() {
    return (
      <button>
        {this.count}
      </button>
    );
  }
}

Notice how the click handler doesn’t need to be attached directly - it’s scoped to the component!

Stencil sounds like a great match for creating design systems and component libraries, as its trivial to create self-contained components with small dashes of logic on it. It works in a lot of contexts, and Stencil itself is pretty light-weight.

If that sounds like your use case, give it a shot today! Get started on their official website!

Open Source Session Replay

OpenReplay is an open-source, session replay suite that lets you see what users do on your web app, helping you troubleshoot issues faster. OpenReplay is self-hosted for full control over your data.

replayer.png

Start enjoying your debugging experience - start using OpenReplay for free.


If you’re tired of reading yet another React or Vue tutorial, or if Svelte just isn’t doing it for you, there are lots of different options out there for you to try out. Some are based on the Web Components spec, while others are more similar to React in nature and design. A common trait for them all is that they’re definitely pushing the status quo for how front end development should be, and that’s where we need them to be.

Hope you give them a shot next time you’re starting something new!