Internal Data Structures of Solid.js

For who-knows-how-long, I’ve dabbled in web gui sorcery. It costs me sanity to lift the “develop-friendly” facade, and look at the inner workings of a web ui library.

This week, I did the unthinkable again, and looked at how the library-user-facing side of Solid works. I felt… nothing. That’s a good thing. I need to share the great news to you all.

For simplistic’s sake, this article is only correct about the library’s behavior in browser. On Node.js it’s not much different, except the DOM elements are replaces with Solid’s own greeting. We also don’t talk about reactivity here. Ask Ryan to explain that for you. It’s too ingenious for me to understand (at the time of writing).

“Components? We don’t do that here.”

For Solid, “component” is a meme.

See <p>hi</p>? Oh, it’s just a DOM element. The HTMLParagraphElement thing.

What about <></>? [].

What about <>p</>? "p". Yes it’s just a string. Seems like when the fragment only contains one thing, it’s not an array.

What about <>hi<br/></>? ["hi", (HTMLBRElement)].

What about <>hi{a()}</>? It’s ["hi", X] where X is a() evaluated. It works like string interpolation in JS.

“But how do I component?”

That’s simple. Just do const Greeting = (props) => <p>hi there</p>.

To instatiate a component, do <h1><Greeting a={1}/></h1>. It’s the same as

<h1>{Greeting({a:1})}</h1>

Note that the component is created before the outer element tree is created. In fact, it is the same as nested function calls.

The nested stuff is passed as children verbatim. That’s why you can pass function and other data types as component children. Example:

let a = <A>{1}</A>
// is same as
let a = A({children:1})

let b = <A>{1}{2}</A>
// is same as
let b = A({children:[1,2]})

Same as fragment (<></>), if the nested stuff are two or more, it’s passed in as array.

By the way, JSX assumes that if first letter of an element is lower, the element is a native element. So you can’t write <greeting/>. Use {greeting()} (if you name the component lowercase).

“What about the special elements like <For>?”

Special? It looks like a function to me.

const a = <For>...</For>
const b = <>{a()}</>

Conclusion

  • A “component” in Solid is a function that returns a DOM element, or an array of those.
  • It is possible to make a simple web ui library without insanity-inducing details.