An Introduction to Solid.js
Getting Started
As part of our framework series, we'll now explore the basics of Solid.js. Solid is quickly gaining sympathy and adoption as a JavaScript framework designed for building fast user interfaces with maximum control over reactivity.
Created by Ryan Carniato in 2018, Solid.js is known for its pragmatism and exceptional performance. While it shares similarities with React, such as using components and JSX, it takes a different approach under the hood — eschewing virtual DOM and adopting a compiler like Svelte, which translates our code into efficient vanilla JavaScript.
Unlike React, JSX directly maps to real DOM elements, removing unnecessary abstractions. So, this means that the framework only updates the parts of the DOM that have changed. The result? Incredibly fast and efficient updates.
The framework weighs a mere 7 kilobytes, boasts impressive runtime performance, and requires no special tricks to achieve its speed. Solid.js is truly reactive, featuring a function component that's only called once, allowing for unprecedented control.
Moreover, it has excellent TypeScript support, further enhancing our developer experience.
Trying Solid.js
There's a lot of novelty involved in web development. So, to ease the experience we strongly suggest trying it online first, in the official Solid playground. If you wish to modify and experiment with the examples you can use a code sandbox where you can easily sign up using your GitHub account.
Before jumping in, we suggest brushing up your JavaScript ES6 syntax
Components and Composition
As we dive into the world of Solid.js, the first thing we need to understand is the concept of components. As is the case with other modern frameworks, we use components to create modular, reusable pieces of UI. Not only we can make our codebase easier to maintain, but we can also promote a clean separation of concerns.
Creating a Simple Component
Let's take a look at a basic Solid.js component. Imagine we're building a website that displays a list of our favorite books. We might start by creating a Book component to represent each book.
import { createSignal } from "solid-js";
function Book(props) {
const [likes, setLikes] = createSignal(0);
function handleClick() {
setLikes(likes() + 1);
}
return (
<div>
<h3>{props.title}</h3>
<p>Author: {props.author}</p>
<button onClick={handleClick}>Like</button>
<p>{likes()} likes</p>
</div>
);
}
export default Book;
We've created a Book
component that takes props
as an argument. We use these props to pass data down to the component, like the book's title and author. The component also has a local state for tracking the number of likes, which we manage using the createSignal
function imported from the solid-js package.
Basically, we created a reactive signal, that represents the fundamentals of reactivity in Solid. The core primitive createSignal
returns a getter and a setter; the first function returns the current value of the signal, while the latter updates the value.
Check out Solid's other primary primitives.
Composing Components
Now that we've got our Book component, we can use it to build a more complex UI. Let's create a BookList
component to display a list of books.
import Book from "./Book";
function BookList() {
const books = [
{ title: "The Catcher in the Rye", author: "J.D. Salinger" },
{ title: "To Kill a Mockingbird", author: "Harper Lee" },
{ title: "1984", author: "George Orwell" },
];
return (
<div>
<h2>My Favorite Books</h2>
{books.map((book) => (
<Book title={book.title} author={book.author} />
))}
</div>
);
}
export default BookList;
We've imported the Book
component and used it inside the BookList
component demonstrating the flexibility of component composition in Solid.js with small, reusable components that we can combine to create more complex UIs.
JSX and Templating
We might find this familiar if we've been exposed to other JS frameworks. Solid.js leverages JSX, a templating language in the React ecosystem, to define the structure and appearance of components. With JSX, we can write HTML-like syntax within the JavaScript code, making it more readable and easier to reason about.
How Solid.js Uses JSX
However, JSX isn't only used for defining the structure of components, but also for handling dynamic content and logic. Let's take a closer look at the component we created earlier.
return (
<div>
<h3>{props.title}</h3>
<p>Author: {props.author}</p>
<button onClick={handleClick}>Like</button>
<p>{likes()} likes</p>
</div>
);
Notice how we're using curly braces {}
to embed JavaScript expressions within the JSX. This allows us to easily display dynamic content like the props passed to the component or the current number of likes. Also, note that we're using the onClick
attribute to handle click events on the button, as a prime example of how JSX can help us handle events and user interactions seamlessly.
Final Thoughts
We've laid down the foundations, but Solid also contains some uniquely-approached features. Some of them include:
Stores for added granular reactivity
Fine-grained control over component lifecycles
Automatic dependency tracking
Suspense and error boundaries for handling async data and errors
Custom elements and web components integration
As you venture deeper, there's a wealth of resources available to help you hone your skills and deepen your understanding. Feel free to go over the curated resources below, to assist you on your journey.
Useful Resources
Official Solid.js Documentation
Introduction to Svelte - The Lightweight JavaScript Framework