DEV Community

Tomasz Wegrzanowski
Tomasz Wegrzanowski

Posted on

Open Source Adventures: Episode 43: SolidJS

Let's take a look at some of the new frameworks. SolidJS looks very much like Hooks-style React, but apparently it abandons virtual DOM.

I never used it before, so let's start with a hello world app, and over the next few episodes I'll try to build something a bit more substantive.

Getting started

We can start it with degit, which seems to be the most popular tool for a lot of frameworks these days:

$ npx degit solidjs/templates/js episode-43
Enter fullscreen mode Exit fullscreen mode

Then we do the usual steps to start the app:

$ npm i
$ npm run dev
Enter fullscreen mode Exit fullscreen mode


We can start with cleaned up index.html, it's pretty much what you'd expect:

<!DOCTYPE html>
<html lang="en">
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Solid App</title>
    <div id="root"></div>
    <script src="/src/index.jsx" type="module"></script>
Enter fullscreen mode Exit fullscreen mode


This comes from the template as well. I'm not sure what /* @refresh reload */ is for, most likely something related to HMR.

/* @refresh reload */
import { render } from "solid-js/web"

import "./index.css"
import App from "./App"

render(() => <App />, document.getElementById("root"))
Enter fullscreen mode Exit fullscreen mode


SolidJS has both global and (awkward coming from Svelte) module-scoped CSS. For this app I'll just use global CSS:

body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  text-align: center;
  justify-content: center;
  align-items: center;
Enter fullscreen mode Exit fullscreen mode


It looks very close to React with useState. It's not quite the same, as semantics are very different, and you access current value of count with count() not just count. But for simple cases, it should be easy transition for React developers.

import { createSignal } from "solid-js"

function App() {
  let [count, setCount] = createSignal(0)

  return (
      <div>{ count() }</div>
      <button onClick={() => setCount(count() + 1)}>Click me!</button>

export default App
Enter fullscreen mode Exit fullscreen mode

Building the app

To build the app, use npm run build, and it will be created in dist... And once again it will not work for GitHub Pages as it uses absolute paths. I have no idea why so many frameworks have this awful default.

We need to modify vite.config.js to use relative paths. Fortunately that's just one line change base: "./":

import { defineConfig } from "vite"
import solidPlugin from "vite-plugin-solid"

export default defineConfig({
  base: "./",
  plugins: [solidPlugin()],
  build: {
    target: "esnext",
    polyfillDynamicImport: false,
Enter fullscreen mode Exit fullscreen mode

Story so far

And here's the result:

Episode 43 screenshot

I deployed this on GitHub Pages, you can see it here.

Coming next

In the next few episodes, we'll try to build some less trivial things with SolidJS.

Top comments (0)