A while ago, I wrote a post 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, 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 (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 (not S.O.L.I.D. principles, 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, going toe to toe with vanilla JS!

Coding demo

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

// 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. 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, 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?

#framework #javascript #typescript

Solid - The best JavaScript UI library?
1.10 GEEK