solidjs /solid

A declarative, efficient, and flexible JavaScript library for building user interfaces.

★ 36,358⑂ 1,157👁 228⑃ 1,666● 2,019▤ 217◈ 825
TypeScriptMITCreated 2018-04-24solidjs.com
36,358
stars
+5
1,157
forks
228
watchers
1,666
prs
2,019
issues
217
releases
825
discussions

README

Website • API Docs • Features Tutorial • Playground • Discord

Solid is a declarative JavaScript library for creating user interfaces. Instead of using a Virtual DOM, it compiles its templates to real DOM nodes and updates them with fine-grained reactions. Declare your state and use it throughout your app, and when a piece of state changes, only the code that depends on it will rerun.

 At a Glance
tsx
import { createSignal } from "solid-js";
import { render } from "solid-js/web";

function Counter() {
  const [count, setCount] = createSignal(0);
  const doubleCount = () = count()  2;
  
  console.log("The body of the function runs once...");

  return (
    <
       setCount(c = c + 1)}
        {doubleCount()}
      
    
  );
}

render(Counter, document.getElementById("app")!);


Try this code in our playground!


Explain this!

tsx
import { createSignal } from "solid-js";
import { render } from "solid-js/web";

// A component is just a function that returns a DOM node
function Counter() {
  // Create a piece of reactive state, giving us an accessor, count(), and a setter, setCount()
  const [count, setCount] = createSignal(0);
  
  //To create derived state, just wrap an expression in a function
  const doubleCount = () = count()  2;
  
  console.log("The body of the function runs once...");

  // JSX allows you to write HTML within your JavaScript function and include dynamic expressions using the { } syntax
  // The only part of this that will ever rerender is the doubleCount() text.
  return (
    <
       setCount(c = c + 1)}
        Increment: {doubleCount()}
      
    
  );
}

// The render function mounts a component onto your page
render(Counter, document.getElementById("app")!);


Solid compiles your JSX down to efficient real DOM updates. It uses the same reactive primitives (createSignal) at runtime but making sure there's as little rerendering as possible. Here's what that looks like in this example:

js
import { template as _$template } from "solid-js/web";
import { delegateEvents as _$delegateEvents } from "solid-js/web";
import { insert as _$insert } from "solid-js/web";
//The compiler pulls out any static HTML
const _tmpl$ = /__PURE__/_$template(Increment: );

import { createSignal, createEffect } from "solid-js";
import { render } from "solid-js/web";

function Counter() {
  const [count, setCount] = createSignal(0);
  
  const doubleCount = () = count()  2;
  
  console.log("The body of the function runs once...");
  
  return (() = {
    //_el$ is a real DOM node!
    const _el$ = _tmpl$();
    _el$.$$click = () = setCount(c = c + 1);
     //This inserts the count as a child of the button in a way that allows count to update without rerendering the whole button
    _$insert(_el$, doubleCount);
    return _el$;
  })();
}
render(Counter, document.getElementById("app"));
_$delegateEvents(["click"]);




 Key Features

- Fine-grained updates to the real DOM
- Declarative data: model your state as a system with reactive primitiv

Top issues

Discussions

Latest release

v1.9.0 - LGTM! v1.9.0 2024-09-24
This release like the last is focusing on small quality of life improvements and adjustments that will help us move towards 2.0. So while not the most exciting release to everyone it provides some really important features and fixes to some developers.

And unlike many previous releases the vast majority of the work and features came from PRs from the community. So really all I can say is Looks Good to Me!

 Better JSX Validation

While still incomplete across templates we've added JSDOM to the compiler to better detect invalid HTML at build time by comparing what we expect the template 

Snapshot: 2026-11-10T09:35:25Z · Data license Apache-2.0 · JSON