Solid - The best JavaScript UI library?
Tags: webdev, javascript, typescript
Published: 2020-09-07 18:13:31

A while ago, I wrote a  [post](https://areknawo.com/svelte-a-recipe-for-a-successful-framework/)  on some of the most important advantages of  **Svelte**. Back then, the framework had just received a major update, and it was quite a hot topic to cover. Now, after the dust has settled, Svelte still has a lot going for it, but it also has some drawbacks that previously went unnoticed.

I don't want to rant over these small issues because that's not the point of this article, and besides - I really like Svelte! But for your information, these are:

-   **TypeScript support**  - although  [it's been added recently](https://svelte.dev/blog/svelte-and-typescript), it wasn't there at the time Svelte exploded in popularity. Thus, most of its still small, but very important for the framework ecosystem will most likely not support it.
-   **Syntax differences**  - Svelte feels good when you get used to it, but because of its  **compiler-based**  nature, there are some syntax nuances that newcomers might find a bit awkward, like the dedicated template syntax,  `$:`  reactive label (although it is technically valid JS), etc.
-   **Small ecosystem**  - this is a common issue that unless you're React, Vue, Angular, or [insert your big framework here], or you're 100% down on  **Web Components**, you're doomed to experience. Because of Svelte's recent growth in popularity, it developed a pretty-respectable ecosystem, and because of  [its good support for Web Components](https://custom-elements-everywhere.com/libraries/svelte/results/results.html)  (you can even compile Svelte to such), it's not as big of an issue, but still, something to keep in mind.

So, Svelte is not ideal - nothing is - and that's why we have  **alternatives**. If the idea of the compiler is very attractive to you and you want to have top-to-bottom TypeScript compatibility without Svelte's syntactic gotchas, you might be interested in  **Solid**.

# Solid introduction

So,  [Solid](https://github.com/ryansolid/solid)  (not  [S.O.L.I.D. principles](https://areknawo.com/10-coding-principles-and-acronyms-demystified/), but  **Solid UI library**) is  _"a declarative JavaScript library for creating user interfaces"_. So, yet another UI framework? Well, yes, but also no. You see, Solid introduces some nice mixtures of concepts that we haven't seen before, effectively making itself stand out from the overpopulated UI libraries crowd.

What does Solid have going for it? For me there are a few things: it's written in and has first-class support for  **TypeScript**, it supports  **JSX**, with additional React vibes like Fragments, async rendering, and hook-like functionalities, and last but not least - it's  [wicked-fast](https://krausest.github.io/js-framework-benchmark/current.html), going toe to toe with  **vanilla JS**!

# Coding demo

I hope I sparked your interests. Now, let's examine an example Solid component.

```javascript
// index.tsx
import { Component, createState, onCleanup } from "solid-js";
import { render } from "solid-js/dom";

const App: Component = () => {
  const [state, setState] = createState({ count: 0 });
  const timer = setInterval(
    () => setState("count", (count) => count + 1),
    1000
  );

  onCleanup(() => clearInterval(timer));

  return <div>{state.count}</div>;
};

render(() => <App />, document.getElementById("app"));
```

Above you see a simplistic  [counter component](https://codesandbox.io/s/8no2n9k94l). If you've worked with  **React**  before it should feel somewhat familiar to you.

We create our  `App`  component through the use of an arrow function, with a directly-specified  **type**. It's a little tidbit to remind you that Solid works great with TypeScript.

Next up you can notice the use of the  `createState()`  function, together with familiar array  **destructuring pattern**.

This might look a lot like  [React hooks](https://reactjs.org/docs/hooks-intro.html), but only on the outside. On the inside, there are no  _"rules of hooks"_  to oblige to and no issues or confusion around stale closures. That's because the components in Solid are  **run only once**, leaving reactivity and all the re-executing to specialized parts of the code (like callback passed to  _"Solid hooks"_). To make it even more clear, React invokes the  `render()`  method or its functional component equivalent on every re-render, whereas Solid uses its component function as sort-of a "constructor", which runs only once, to set up all the other  **reactive parts**.

So, we've got our state. Now, we use the usual  `setInterval()`  function for the counter functionality, and  `setState()`  in a reducer-like manner (one of many possible ways to use  `setState()`  in Solid), to update the state.

Lastly, we use the hook-like  `onCleanup()`  function to register the callback for handling  **component disposal**. Remember, because the core component function is run only once, "hooks" such as  `onCleanup()`  are the only way to handle reactive behaviors.

Now, just return the JSX element, render the component and you're done! Isn't that complicated, is it?

# Things to keep in mind

So, this was just a simple demo to give you some basic understanding of how things look like. For more in-depth guidance check out  [the official docs](https://github.com/ryansolid/solid#documentation), or  **drop a comment**  if you'd like to see a full-blown tutorial.

But right now, I'd like to point out a few things that you should keep in mind if you're willing to try out Solid.

First off, I know I repeat myself, but the fact that the component function is  **run only once**  is very, very important. Because Solid uses JSX and is inspired by React, it's safe to assume that the developers who'd like to use it would be at least somewhat familiar with React and could (possibly) be confused as to why their code isn't working properly. Knowing about this difference is  **crucial**  to get accustomed to the Solid's approach.

Next up, because Solid is a  **compiler**, it requires additional setup for proper development experience. The easiest way to do this is through a  **Babel plugin**  ([babel-preset-solid](https://github.com/ryansolid/solid/tree/master/packages/babel-preset-solid)), or by starting with a pre-configured boilerplate:

```bash
npm init solid app my-app
```

Because modern web development already relies heavily on tools such as Babel, adding another plugin shouldn't be much of a problem.

Lastly, there are even more things to remember about Solid's  **reactivity**. Because of heavy optimizations and compiler-based design, there are a few gotchas when working with  **the state**. The most important of which is that you  **shouldn't destructure the state**, like so:

```javascript
const { count } = state;
```

The value derived from destructuring  **won't be reactive**, and thus won't be updated when used in JSX. If you really can't stand constantly having to enter the full state property path, then (apart from having some truly unwieldy state object), you can still handle that like so:

```javascript
const count = () => state.count;

// later
count();
```

What you do is essentially creating a  **thunk**  (or simply a  **shortcut**) to access the state property. It might be a bit of a waste when dealing with simple states, but can also be really helpful when dealing with 2 or more levels of depth.

But for really simple, one-property states like in the previous example, using objects is an overkill all together. For such cases, Solid provides so-called  **Signals**  -  _"atomic immutable cells that consist of a getter and setter"_. Basically, a tiny version of state objects, but with a few differences.

```javascript
import { createSignal } from "solid-js";

const App = () => {
  const [getCount, setCount] = createSignal(0);
  //...

  return <div>{getCount()}</div>;
};
```

The  `createSignal()`  method, returns a pair of functions, from which the first one can be used to access the hold value and the second one to set it.

As you can see, signals are somewhat like a dumb-down version of an object-based state, but only somewhat. You see, Solid uses signals as building blocks for the more advanced reactive functionalities. This includes the object-based state, which at its core is a  **proxy**  composed of smaller  **on-demand signals**.

To summarize, if you're willing to give Solid a try, then it's quite important to understand its concepts for creating efficient code without compromising too much on development experience.

# Drawbacks

Before we declare Solid  _"the next big thing"_, or the  _"best JS UI library"_, it's worth pointing out some of its  **drawbacks**, which honestly there aren't that many.

From the Solid's as a UI library standpoint, we might argue that all the API and syntax gotchas I've listed, as well as the ones that I didn't, can be considered a drawback. However, we can't expect a simple UI library to go against the very nature of software. The limitations of both JavaScript itself, as well as Solid's compiler-based design, do require some  **tiny compromises**. Which still, at least in my opinion, once you get used to, they shouldn't be much of an issue.

Secondly, of course, the  **ecosystem**  is small. At the time of writing the library has about  **~4K GitHub stars**, and a fair bit of articles have been written about it. But there's still little to no ecosystem developed around it. There's no component library as  [Vuetify](https://vuetifyjs.com/)  is for Vue and  [Material UI](https://material-ui.com/)  for React. All you have is what you write, plus the  [Web Components](https://custom-elements-everywhere.com/libraries/solid/results/results.html)  if you're willing to use those.

And lastly, I'd say the  **docs**  are quite detailed and explain the topic quite well, but they're only Markdown files living in the GitHub repo with no flashy  **landing page**  or anything like that. I know, I know - I'm nitpicking right now, but there needs to be some  _"ethical marketing"_  done to get developers interested in a library - otherwise, you'll only learn about it from benchmarks and articles like this one. The docs are already good enough, the logo is looking nice, and there's a fair bit of example projects ready for you to see, just - there's no landing page.

# Is this the future?

To wrap this up, Solid is a really  **promising UI library**  with tons of advantages. The familiarity of JSX and React concepts and the speed and bundle size of Svelte make it seem like an ideal UI library.

The few drawback that Solid has either aren't that bad, or can be easily fixed, as the library continues to evolve.

Overall, it gets my  **solid recommendation**  (see what I did there?), and I highly recommend you check it out. Oh, and come back after you do and  **let me know your thoughts**  in the comments below!

For more up-to-date web development content, be sure to  **follow me**  on  [Twitter](https://twitter.com/areknawo),  [Facebook](https://www.facebook.com/areknawoblog)  or through  [my personal blog](https://areknawo.com). Thanks for reading and I wish you S.O.L.I.D. coding!