SolidJS with Ryan Carniato - JSJ 528

SolidJS is a web development framework that focuses on using reactivity and carries forward several ideas from Knockout.js. https://javascriptjabber.com/13 Ryan Carniato, the creator of SolidJS breaks down the history and ideas behind SolidJS and compares it to React and other frameworks.

Special Guests: Ryan Carniato

Show Notes

Transcript



CHARLES MAX_WOOD: Hey everybody and welcome back to another episode of JavaScript Jabber. This week on our panel, we have AJ O'Neill. 

AJ_ONEAL: Yo, yo, yo. Coming at you live from the standing desk. 

CHARLES MAX_WOOD: Dan Shapir. 

DAN_SHAPPIR: Hey from very cool Tel Aviv. 

CHARLES MAX_WOOD: Steve Edwards. 

STEVE_EDWARDS: Howdy from the left coast here in Portland. 

CHARLES MAX_WOOD: I'm Charles Max Wood from Top End Devs. And this week we have a special guest and that's Ryan Izzacarniato.

RYAN_CARNIATO: Yeah, that's Carniato. I'm glad to be here. 

CHARLES MAX_WOOD: Yeah. So somebody said something about Solid.js and I was going to ask something about something, something, why, why not use React? But anyway, why don't you introduce yourself real quick and then we can, we can dive into what Solid is and why it exists and what it does. 

RYAN_CARNIATO: Sure. Yeah. My name's Ryan Carniato. I created Solid.js. I guess almost five years ago, I've been just working on open source. I asked...I actually work at eBay. I work on their open source framework there as well, MarcoJS. So I work on two JavaScript frameworks. And I'm kind of very passionate about benchmarking and performance and reactivity. I just love fine-grained reactivity, which we'll probably talk about a bit today. 

CHARLES MAX_WOOD: Cool. 

 

Hey folks, this is Charles Max Wood from Top End Devs. And lately I've been working on actually building out Top End Devs. If you're interested, you can go to topendevs.com slash podcast, and you can actually hear a little bit more about my story about why I'm doing what I'm doing with Top End Devs, why I changed it from devchat.tv to Top End Devs. But what I really want to get into is that I have decided that I'm going to build the platform that I always wished I had with DevChat.TV and I renamed it to Top End Devs because I want to give you the resources that are gonna help you to build the career that you want, right? So whether you want to be an influencer in tech, whether you want to go and just max out your salary and then go live a lifestyle with your family, your friends, or just traveling the world or whatever, I want to give you the resources that are gonna help you do that. We're gonna have career and leadership resources in there and we're gonna be giving you content on a regular basis to help you Go check it out at topendevs.com. If you sign up before my birthday, that's December 14th. If you sign up before my birthday, you can get 50% off the lifetime of your subscription. Once again, that's topendevs.com. 

 

CHARLES MAX_WOOD: Well, yeah, let's just dive in. So maybe we'll have you back to talk about MarcoJS, but let's talk about Solid. Do you wanna just give us an idea of what it is and maybe why we need yet another approach to some of these problems? 

RYAN_CARNIATO: Yeah, for sure. Solid.js is a JavaScript framework that's built on the concept of fine-grainy activity. You may have seen it before in things like MobX and even Vue to a certain degree, but its roots actually rely further back. Something, an older framework called Knockout.js. I was very enamored with Knockout.js. It had its flaws. It was kind of chaotic at times, but what kind of happened over the years, especially with the MobX is that.. we've gone to a point where the execution was much more predictable and batching. And we kind of got a lot of the issues with it had kind of gone away, but I've always liked that paradigm because it was based off these primitives that you can build your UIs from. Like you just have these simple things, you know, like a observable or computed, and then you just compose it on, on top of each other and build your UIs that way. And I thought this was always really, really powerful. So, to tell you the truth, when React came out and did the class life cycles and stuff, I just wasn't really a fan. We were used to these kind of more modular behavior-oriented approaches at my startup. And over time, Knockout fell out of favor. People stopped using it as much. And I was like, okay, well, maybe I'll make a... We already kind of managed our own tooling a lot because my boss, when I first started, though he moved on, was the creator of Knockback, which was a backbone Knockout library. So I kind of got thrown into open source and I was maintaining these libraries to a certain degree and our stack at the startup and I was like, okay, well I want to improve it. So I was like, let's see if we can replace knockout with something else. And that's how I started working on this because I realized like we could. 

DAN_SHAPPIR: You use the term reactivity in the context of a UI and a framework. Now what does that exactly mean? Is it like a one way data binding? What do you mean exactly when you say using reactivity to compose a user interface. 

RYAN_CARNIATO: Yeah. 

CHARLES MAX_WOOD: Can I interject real quick before that? If you're interested in Knockout and what the history is there, episode 13 of JavaScript Jabber, we talked to Steven Sanderson about it. So, and he's the guy that created that. So anyway, go ahead. 

RYAN_CARNIATO: Okay, yeah. Mostly, and this is where the kind of more interesting detail get is, because it starts with these primitives, like three primitives. They're called different things in different languages, they're different frameworks, but a reactive atom called a signal, some kind of side effect creating thing. We call them create effect, but it's sometimes called computed or auto run in different frameworks. And then kind of derived pure derived value which we call memos. Again, some of our naming seems to have a lot lined with React, but generally speaking, the way Solid works is the whole tree is actually made of just these primitives. There's no virtual DOM per se. It's more of like, these kind of expressions wrapping through closures around specific updates. So like if you like you could if you're familiar with React, you can you could almost picture use effect but in the effect is just to update this one point in the DOM and with reactivity it's triggered off an auto tracking mechanism. This those pieces are very similar and haven't changed from knockout at least on the API side. Like you have these signals or observables that are run or execute underneath the effect or computed. And whenever that effect or computed runs, it collects those basically listens for those getting accessed. And the next time any of those values change, it reruns that effect. And basically with Solid, we've managed to compose the whole tree based off of that, if that makes any sense. So I guess it's like data binding, but it's... I often don't talk about it the same way, but I guess it is similar. 

DAN_SHAPPIR: The analogy that I've heard in the past when describing these types of system and which might help people to kind of grasp the concept and correct me if I'm wrong here, is that of a spreadsheet where you have certain cells bound to computations that use other cells as input. And then what I'm hearing in your case is that I have some variables in memory that when they update, that automatically triggers code that updates a certain part of the user interface, which presumably depends on that value. Is that a correct description, more or less? 

RYAN_CARNIATO: Yes. Yeah. The spreadsheet is a good example. 

DAN_SHAPPIR: And the reason that I kind of use the term data binding is a lot of people, thanks even to Angular and other frameworks, are familiar with the concept of data binding, bit of UI is bound to, let's say, a field in a database. And then when one updates, the other changes as well. But data binding is usually two-way. What you described seems to be more like one-way, where it's not necessarily a database field. It's just a value of memory. But when that updates, that triggers the UI update. But the UI doesn't automatically write the value back to that cell in memory or something like that. Is that correct as well? 

RYAN_CARNIATO: Yeah, we generally do one way binding, a unidirectional flow. So yes, that sounds correct. 

AJ_ONEAL: And that's basically the idea behind most reactive frameworks, right? Is that you have one directional flow because that's what makes it reactive. If it was two directional, it wouldn't be reactive, right? 

RYAN_CARNIATO: The early frameworks were all like reactive frameworks like Knockout did use a lot of two way binding. It was a deliberate choice and that one inspired by React to not use two-way binding. You still see two-way binding in Spelt and Vue and I guess Angular, although they've all moved to explicit two-way binding because they don't want, two-way binding can be dangerous. In Solid's case though, we don't actually do two-way binding pretty much at all. 

AJ_ONEAL: Well, let me try to define this then. Because in my mind, when I think of two-way binding, when I think of one-way binding, what I think of is, you have to actually call a function or take an explicit action in order for...dated a change. And when I think of two way binding, I think if I set a property on an object, there's some sort of magic, some sort of quote unquote, observable or timer or something that is manipulating the object in a weird non JavaScripty way to to understand that something changed without you actually saying, hey, go, go take an action on this. Is that the way that we're speaking about it? Or how would you define it?

RYAN_CARNIATO: It's interesting because for me, that's a gray area. That's one of the things that I did a lot with solid. I blurred the lines on these sort of topics. Like solid does have that mutable underpinnings, especially like when we have proxy objects and stuff, which some of our reactivity is based off of. But I made a deliberate choice to make all of those interfaces immutable. So essentially everything's read, write segregated. So we don't actually update based off assignment. Everything is called from an explicit setter, but under the hood mechanically it is closer to the libraries like you're describing. It was like a philosophical choice. 

DAN_SHAPPIR: So to sum it up basically, when we have a certain store of data, which we'll talk about I guess in a bit how that actually, what actually represents that store of data, but we have some sort of storage of data, when that data changes, that triggers some code to execute. You called it sort of like use effect. That code updates the user interface. On the other hand, if there is an event from the user interface, I need to actually sort of capture that event and use that event to actually trigger some sort of a setter to explicitly change data, which could again obviously always trigger another effect to update the user interface and probably does. That would be more or less an accurate description. 

RYAN_CARNIATO: Yes. Yeah, that's correct. 

DAN_SHAPPIR: But the interesting thing is that I've looked at some solid code ahead of this podcast. And on the one hand, it's obviously very reminiscent of React and I guess intentionally so. I think it also uses JSX for example. But on the other hand, if there's one thing that I didn't actually see in the code, it's use effect. So either I missed it or you somehow implement use effect without actually implementing use effect. 

RYAN_CARNIATO: Yeah, we do have, it's called create effect. So we do have one. You might not... Yeah, I mean, useEffect isn't always used a lot in React. Like it's the escape hatch and people manually using createEffects fall into basically the same category of their usage. Solid uses effects under the hood to do the rendering. But like for the end user code where they'll need effects are usually going to be like those like small things like, you know, updating a title or something that needs to kind of interact with the outside world. And Solid has primitives for async which actually are one of the other big places where people use effect. So because we have a kind of a special signal that's designed to handle promises, the patterns that people use when developing apps might not necessarily lend to using, you know, create effect all over the place. They'll just go like pass this promise in and then they get a signal, so to speak. 

STEVE_EDWARDS: So in other words, it can be a very effective way of using the code, right? 

DAN_SHAPPIR: Yeah. What I mean though is that, for example, sorry Chuck, Hugo, I've taken over the conversation. 

CHARLES MAX_WOOD: We're talking a lot about how this works, and I think for the most part, if you've used something that uses this one way data binding, you're pretty familiar with the way things flow through, and it sounds like it uses some pretty familiar patterns. My question is, how do any of these differences actually materialize into...a better experience for me or for my users or whatever. So is it faster? Is it easier to write? Is it prettier? It's just, hey, you might like this approach better. I mean, what are we looking at? 

RYAN_CARNIATO: Yeah, okay. There's two things here. If you're coming from a React perspective, I do think reactivity appears to be simpler to write than hooks are. They don't have the same stale closure rules or most of the hook rules. There are trade-offs and you see this in Vue as well. And MobX where destructuring or accessing things outside of the context is something to be aware of because it matters where things are accessed. But generally speaking, you don't have Vue's callback. You don't have Vue's ref. There's not this model of the whole component rerunning. So in React, often you have to be like, oh, what updated this time to cause the component to rerun for these hooks to run? But state of mind. Basically, there's never really need to have like a use ref for something that's not a DOM ref. And that kind of simplification really sort of helps a lot of people when they kind of approach it. But like to be fair, Svelte and Vue have this characteristic as well. Solid similarity look to react makes this probably more impactful for people because people assume that you needed a template via Svelte or you needed some other characteristics to achieve this. And in our case, we're saying no, you don't. You can use JSX and whatnot. The other side is Solid is unique in a different sort of way. It is the first to my... Well, not the first, but it's the first to gain popularity of a rendering technique based on this granularity of change. Like even with Vue or Svelte, they still rerun components. I mean, Svelte's compiler will split the code in half between a create and an update cycle, but essentially everything's like this component level granularity in terms of how things are rerun. So like...something changes here and in stealth's case, the let belongs to the component. So if you update that lettable, then that component reruns. In Vue, kind of the same idea. It won't rerun their setup function, it'll rerun their whole template. In Solid, the granularity applies all the way down right into the JSX to almost like a binding basis. So when you change one piece of data, it literally can just go, okay, where are the places in the DOM that it updates and just go...pinpoint and just run those things. And to be fair, like, knockout did this too, but we haven't seen this for quite some time. And this does lead to a lot of performance on the update side. But the trade-off, obviously, classically, was the performance on the creation side, because you're creating a lot of these subscriptions and stuff. So we countered that by being able to analyze the JSX and using the compiler in such a way that we don't have to like walk over the DOM to create the bindings or whatnot, we can actually generate optimized DOM code at compile time, where we know exactly where all the kind of bindings, so to speak, go in. And this lets us separate, how should I put it, the DOM creation code from the binding code, in a sense. And then we can use optimal techniques like cloning DOM nodes, stuff you see in like lit, to basically very quickly create the DOM and then pinpoint add the bindings. And as this turns out, isn't only more performant on update, it's actually more performant on creation. So it's kind of, that's where Solid kind of got its first bit of attention was because in benchmarks, it basically just averaged out to have the considerably good performance across the board, across different types of tests. 

DAN_SHAPPIR: One thing that, sorry, we're kind of diving into the, or diving into the details, and I think it's worthwhile to mention that when you look at Solid.js code, one of the things that struck me,is again how similar it looks or feels to React. I mean, the other frameworks that you mentioned that use a different approach, you mentioned Vue or you mentioned Svelte, they obviously have a very different syntax than what people are, most front-end developers are using frameworks these days are in fact probably using React. And those frameworks have a very different look and feel. On the other hand, when I looked at solid, it's deceptively similar. And I'm intentionally using the word deceptively because then it kind of throws you for a loop because in a lot of ways it does behave code that looks similar behaves in a very different way. And I recently saw an example of use where the react of creating a timer component that updates a counter or a timer, like once a second. And the React code obviously had the set interval inside the use effect because the entire render function executes every time that the component needs to update and provides a JSX, which then becomes a virtual DOM and does a reconciliation and whatnot. Whereas the solid code looked almost identical except that the set interval was directly in the quote unquote render function without being wrapped by a use effect which the intuitive reaction of a React developer is, hey, this is going to execute every time we render, but that's not the case because the function doesn't actually execute every time you need to update the user interface. The JSX provides you, I guess, with a one-time kind of template into what the DOM needs to be, but then you drill into those parts of that generated DOM and update them directly without...calling the render function again and again. Is that a more or less accurate description? 

RYAN_CARNIATO: Yeah, that is correct. And I think I understand, like, it's kind of funny. I don't know how to place it, because the similarity to React is in some way, it's intentional, but I didn't expect things to get where we are now. Like I told you, I started working on this in 2016. And there's a couple things that I really liked about React. I liked the unidirectional flow. And because that solves a lot of the problems we had to knock out. And I like JSX because JSX is a primitive. It is a, like, you can just pick up and go, here's a div. And in our case, it is a div. Like when you go a JSX div element and literally go like const div equals JSX div, you get a div element back. I liked that it was, it was like this granular piece that I can just use as I wanted to, can pass it around. Most templating syntax can lock you in. And I was like, no, I just, I just like that these are the building blocks I want to build my UI with. So. JSX is already well typed. It had all the characteristics. It was already built. It was spec. I didn't have to do any work. So as me as one person by myself, I was just like, okay, JSX is already here. You know, I don't have to invent the world again to do it. So I was just going to JSX and reactive printers. And you got to understand at this time, class components were a thing. I didn't think anyone on the react side would ever make something that looked like hooks. Solid was already using hooks before hooks were. thing. That was just the pattern. You use Knockout, they kind of look like hooks. If you state observable, computed, use memo. Or sorry, pure computed, use memo, computed, use effect. There's a definite analog language-wise between these things. So I just picked the things that were the smallest building blocks that I could use to build up to whatever I wanted to build up to because that was my whole thing. I'm big on these little pieces that can be adaptable to how you want to use it and essentially react. I mean, I was fine on my own just doing that. I entered some benchmarks around the end of 2017 or I guess it was early 2018. That's when I open sourced the library because I was like, okay, I want to see how the performance is and can compete in open, you know, in terms of performance. I think I got something really good here. And then a year later, React released React hooks. And that's when I was like, oh my god, they're actually they actually did it. They're telling people to use patterns that look like this. And then I was kind of excited. Some people were like, oh, I guess the job's done, you know reacts now gone this way, you don't need to worry about it. I'm like, no, no, no, no, no. Hooks have a completely different execution. There is something else the way they work. There's hook rules, there's a whole different mental model. I actually think this is something that people would be excited or interested in. So that's when I started writing articles, that's when I started kind of getting out there. And over time, you know, it's turned into this narrative about react versus solid or whatever, but it's funny because that's not really what I was trying to do. My similarity react comes from admiration in terms of principles. And it just so happens that React kind of decided similar things are good too. 

STEVE_EDWARDS: But it's got to be, you know, somewhat of an ego boost to see that other people that are thinking hard about these problems are arriving at the solution, maybe a little late to the party, but arriving at the solution in a similar way. 

RYAN_CARNIATO: Yeah. I mean, and the thing is that drew attention and that's a bit how I ended up at eBay because the sort of experience I had on these granular patterns, we realized could actually apply to hydration and a whole bunch of stuff. And I know that's a little bit off topic, but essentially this way of thinking, it was already there. I didn't invent it. It would just, it was, I just kind of whittled my way through, you know, all the different stuff and looked at the trade-offs and just reshifted everything. And this is where we ended up. I'm not going to say that there aren't like other considerations there that React doesn't have and whatnot, but it just, it kind of just made sense. 

 

Hey folks, I'm here with JD from Raygun. JD, I have to complain. I mean, When I started in tech like 20 years ago, one of the first things they taught me was to use tail and grep to find the problem on a server. And I don't do that anymore. I have to say, Reagan kind of solves that problem for me and picks up all the stuff that really is relevant to the request or whatever that came in. I'm curious, do you find that with kind of the oldsters like me, a common thing or? I think there's definitely better approaches to solving some of these problems now. You know, I always. used to think of logging. I heard this great analogy once. It was like, logging tools are like coffins. Things go in there. They very rarely come out. You know? And you feel safe because it's there, but there's so much noise. Understanding what's important and what's not takes a lot of effort. Yeah, and I mean, often I talk about Reagan's crash reporting product as being like a black box flight recorder. Like, just tell me when the plane blows up, because I need to fix that really urgently. You know? And that's been hugely valuable. You don't need to tell that. That's true. You know, folks, you should just go get ray gun and then you can see when stuff breaks, what matters, you can get it at ray gun.com. They actually are doing a free trial. Let's go check it out. 

 

DAN_SHAPPIR: But correct me if I'm wrong. The main reason that hooks have all this, these rules, and I might even say overhead associated with them that seemingly does not exist in solid is that despite you calling solid the framework or library, it's more akin to an actual programming language. No, I mean, if I understand solid correctly, you kind of compile solid code. Is that not correct? 

RYAN_CARNIATO: So it's half and half. And I think this is one of the places where I want to clarify because there's always this jump. People see React and they're like, oh, who cares? It's just React. And they're like, wait, no, this isn't React. Then they go, oh, so it's React like Spelt. And Spelt does compile everything into language. But Solid is actually mostly runtime. And this is the part that isn't terribly obvious, in that if you didn't use the JSX, you can still have it. We have a tag template literal version, and we have a hyper script version. The UX is a little bit clunkier, because you have to wrap things and functions for them to execute lazily. The JSX handles it for you automatically. But essentially, we're using runtime reactivity like MobX. And the only thing that gets compiled is the JSX code. That's the thing. And in the case of components, it's a very simple compilation. It literally is like, look at this component. If it has a capital letter on it, call it like a function. We don't really have functions. I'm sorry. We don't really have components is my better way of playing it. That's a performance thing that we might want to talk about at some point. But essentially, we just do a little bit of manipulation of the props to make sure that the reactive expressions are wrapped. We use getters, like object getters, on the props object to make sure. So we just look at it during compilation. But the big part of the transform is actually that we do this off, what I was talking about with the real DOM nodes. We extract out the static part of the template, and then we, and which we clone, and then we essentially walk the nodes that we need to, to attach the bindings. And the compiler does that. But like the reactivity, like the use stuff, it's all just runtime, which is kind of crazy because of this granular approach. You kind of get the same benefits as something like Svelte or React for Get or these auto-memoizing compilers, but it's so granular. You don't actually need a compiler to achieve it. 

DAN_SHAPPIR: So let's see, I'm kind of trying to figure out in my head to see that I follow your explanation. If I understand correctly what you're saying, then effectively the render function for a component or whatever you choose to call it. If I understand correctly, it kind of serves two purposes. It's simultaneously the thing that provides the initial tree that describes the DOM node that you construct, the DOM tree that you construct and bind to or put placeholders in or whatever you want to call it. And it's also kind of a one big use effects function, in a sense, that gets triggered or parts of it get triggered when they need to or something like that. Is that a correct explanation? 

RYAN_CARNIATO: Yeah. I mean, it's so much easier when we're looking at the compiled code, but the whole thing is- 

DAN_SHAPPIR: Isn't it always? 

RYAN_CARNIATO: Yeah. It's just the way I can put this is, components don't rerun, the effects do, so to speak. It's like we have nested effects, effects and effects and effects. Those effects-like the nesting happens where there are conditional logic, like loops or control flow. That's the only place where we need to actually do it. If you think about it, if you have a component that's in a component that's in a component, in this kind of model, you don't need to rerun any of those components unless there's some kind of decision that needs to be made up higher up in the parent, like show it or don't show it. So essentially at that point where we make the decision whether to mount or unmount that component, that's where there's the effect. If it's top level, it never gets unmounted, then we don't really need any kind of effect. That top section will only ever run once, and it does all the setup. So essentially, each function component, it just breaks up essentially, as you said, the DOM node creation, and it's just a list of these create effect calls, basically. And there might be components or other DOM nested inside. So like, and...Basically, it's hard to say the state isn't tied to the components at all. It's so can be nested in at every level. And the way this all works is that our, our effects like use effects, that's have their cleanup logic wrapped into them. So stuff that's created in the course of that effect will be released when the effect is unmounted or reruns again. But we know that it won't rerun again unless like you are say hiding or showing your component. So like we basically build these helpers into solid, like some components, that basically kind of memoize guard on those conditionals. And then, I mean, again, it can be pretty technical, but essentially, stuff kind of just runs once, and then only updates up to the nearest effect level where a change happens, whether that's just the binding, or whether that's some parent's conditional, or...a parent of a parent. I'm not sure, does that make sense at all? 

DAN_SHAPPIR: Yeah, I think it does. The one question, one more question that I do have though, is where would you put shared state? I mean, if you've got a component level state, it's pretty, it seems pretty straightforward. You would, you know, create it within that component. But what about if you need to have some sort of a shared state that could impact various components in different ways. How would you handle that? 

RYAN_CARNIATO: There's a couple of ways. I mean, at the most basic level, if we just drew that counter component, and this was in the article, and you wanted to make two counters that use the same state, you can literally just hoist the signal out. Because it's not tied to a component, it's updating, doesn't trigger a component to re-render, it triggers the effects to re-render, like the things that subscribe to it. You get global states simply by just making a signal in a file and importing it. You could basically make a file that's like my store or whatever and just go create signal and then import it in 10 places and you've got global state. I still push people usually towards using stuff like the context API. There's nice dependency injection type patterns. There are benefits in like... For SSR to keep things in the tree, you don't want to necessarily have true globals. So... I think stuff like context API is still really beneficial. We use patterns like that so much react. The biggest difference again, though, is it's solid. If you have a context API that has some reactive variables in it and you subscribe to them all over the tree, and by subscribe, I mean literally just read them somewhere, like use them in the JSX or in some kind of effect or something, when you update them, it doesn't cause the whole tree below them to re-render because it doesn't need to. It just looks and goes, okay, what's subscribe to these things and update them pinpoint all over. And I don't mean pinpoint update the components like things like Jotai. I mean, literally pinpoint update the one place in the DOM that updates. So shared state is really just the same thing. This is part of the kind of mental shift is like all state is shared in a sense. It's only the scope of which it's defined that ends up like giving it any kind of like locality. Like it's just, oh. This was in a function, or component, sorry. This was in a component, so it just lives as long as that component's there, because it's in that closure scope, and when it's released, it's gone. But generally speaking, all state in SOLID is global state. SOLID's kind of like a state library first and Vue library second. Yeah. 

DAN_SHAPPIR: No, one thing that considering the Mobix analogy, because I have used Mobix with React, and I'm thinking along those lines. One of the challenges that you can have when using Mobix is that sometimes it does feel like magic, and that magic can be sometimes difficult to understand. I recall two main issues. One is it's not always trivial to understand why and when things are changing. And the other thing that could be challenging is if you somehow accidentally land yourself in a situation where you're trying to create a circular dependency.

RYAN_CARNIATO: Yeah. 

DAN_SHAPPIR: So those two are still deal with that. 

RYAN_CARNIATO: Yeah, those two are still biggest part. And this comes back to where we talked about. We can't prevent it completely. But this is part of the reason why solid is big on unidirectional flow and immutable interfaces. I found in my experience, I used knockout for about a decade in production that often like while this can't completely alleviate those kind of concerns, often the problems are just stray reads or stray rights and things that you just don't realize are actually impacting things. And to solve that, we have a couple mechanisms. Obviously, you can have, we still have the ability to set explicit dependencies if you want, like a React's dependency rate. We do have an API for that. And the other part, as I said, is making it very clear what the setter is versus what the, like, it's not just an assignment. It's not, like, the thing that always, MobX has a strict mode for this and actions and a different API to do this, but they didn't always is to make sure like, because otherwise, if you have some big mutable proxy that you're passing through your tree, and they reassigning it to different props, by the end, you might end up with some local variable that you assigned. And then it goes, you know, oops, that's reactive and sends it all like throughout the tree and causes chaos. We had stuff like that happen back in the day with knockout. And well, stuff like MobX has drastically improved that because now the execution is predictable in terms of like the way it executes in order in the way that it ensures that things only run once and it doesn't ping pong. It is still possible to literally write an infinite loop with enough degrees of separation. We can catch it and go like, hey, we think you wrote an infinite loop, but we can't really prevent the end user. We don't know until runtime that they have written that infinite loop. But by putting these kind of guards, ensuring certain syntaxes like our setters support where it passes in the previous value, and then you can update it, like the incrementing kind of examples you see, where that way it doesn't register a read, because if you register a read in an effect, and then you write to it in the same effect, you are creating an infinite loop because you updated it and then it runs again, and then update it and it runs again. So basically a lot of safeguards are kind of built in through the API level. And this is why I'm so big on being explicit. I realized that a lot of the foot guns that we saw in these old reactive libraries, which kind of caused them to go to...React solves a lot simply at an API level, like the design level being very explicit. And this is why I'm so big on this in terms of that. There are different ways to solve it, right? Vue solves it by having a VDOM. Like, what's the worst thing that can happen? You just kind of feed it into a VDOM and it'll handle it. You know, if you do some stuff inefficiently, yeah, it'll just diff it. And Svelte's compiler solves it by being very localized. Like essentially...you can't pass reactivity around. I mean, there's two-way binding, but essentially, you have to use these stores or these different mechanisms to do stuff. And it's still very component-based. And you don't have the same amount of flexibility and portability. So with Solid, yeah, sometimes I seem really strict. It's because I understand how important it is that your code running is clear. And for that reason, the APIs are designed in such a way kind of explicit and sometimes people are like, oh, why don't you like do the Svelte thing or whatever. And it's like, there's trade-offs there. Like I don't want to trade off composability. I'm a big, big fan of composability. And I'm not saying Svelte can't find other patterns for that as well. I'm just saying like, there's certain things that I knew that I wanted to accomplish and I saw in React an ability to constrain certain elements, you know, make them explicit that will actually alleviate a lot of the classic problems here. So yeah, if that makes sense. I think the API design was very intentional to safeguard against these things. They were on the top of my mind right from the beginning. That's why, you know, solid does look different than svelte and view and whatnot. And people go like, always like really confused by it on the reactive side because they just come to come to reactivity being like, yeah, that's the easy part. That's why you do it this way. And I'm like, no, I use reactivity because I think it's a very powerful system. It's very adaptable, very performant. But we should be careful and we should design things in such a way where we know we are getting exactly what we desire to be. 

CHARLES MAX_WOOD: So one thing that I'm wondering about, so let's say somebody's listening to this and they're like, you know, this sounds really cool. Maybe there are parts of this that they're thinking, you know, I want to dive into this a little bit more and understand some of the concepts that I'm not as familiar with, but I really want to try Solange, right? I'm thinking I'm going to go put this on the next app, or maybe I'm going to go play with the smaller app and deploy it somewhere where it's easy to deploy to and just see what happens, right? How do I get started with Solid? 

RYAN_CARNIATO: Yeah, the best way right now, it's just our website, is that we put a lot of work into it. And there's a 40-part tutorial. This is very inspired by Svelte. They have these great online small exercise tutorials, which also kind of double up as a feature syntax kind of carousel, so to speak. And we have that. You can go in. You can just try the different examples reactivity is and what it means. We are different to React. So I would definitely start there. There's the full docs up there as well, but the tutorials just make it very easy step by step to seeing the pieces that are installed and how it works. And from there, we have a... And this is also in the get started guide on the web, but we have a bunch of templates that you can just dig it down, which makes it very easy. This is all mostly on the client side, single page app side of things. We are working on a new starter called Solid Start that we're nearing a beta release for, which is essentially a full stack SSR framework, similar to StalkKit or Remix. It has all the file system routing, the automatic SSR, it supports streaming, suspense on the server, adapters for CloudFlare workers or Netlify or whatever deployment for cell you want. In the future, I imagine that's going to be...one of the primary ways to get started. But I think really just start with the website. The tutorials are really great resource. Also, join the Discord, honestly. That's where you find the help. The community has been growing rapidly, and it's the best place to ask questions. There's always people around to answer them. 

CHARLES MAX_WOOD: The Discord link is on the solid website? Y

RYAN_CARNIATO: eah. GitHub, Discord, Reddit, the links are all right there. 

CHARLES MAX_WOOD: Okay. Find everything you need there So I have to ask this question for Steve. Are you ready, Steve, with the drum? But can you use solid with liquid templating? All right, I'm done. 

AJ_ONEAL: I apologize. I apologize on behalf of my fellow friends. Yeah, I mean, I'm...

STEVE_EDWARDS: Sorry, I forgot to mention the studio audience, but they appreciated that. Yeah, I was waiting for that. 

RYAN_CARNIATO: There's always this temptation, there's a billion puns to be made off of Solid. 

CHARLES MAX_WOOD: Yes, yes. 

RYAN_CARNIATO: The thing is, some people know this because I've told this story a couple of times. The name didn't come from like object oriented programming or any kind of thing like that. I was literally just in a punk rock band called Mr. Solid and later Solid as we kind of progressed into a metal core band. Essentially, I just been going around by that moniker forever. I was just like Ryan Solid, you know, kind of like Joey Ramone or something. It was just like the tagged onto the end of my name. And that's my email and all that. And I was like naming things as the hardest thing ever. And I'm like sitting there kind of trying to figure out like what I'm going to call this framework and like not to mention ever go on NPM or like GitHub and trying to get names and see if they're not taken. And surprisingly, I guess to be fair, there is the Tim Berners solid project, which is for the next internet. But other than that, there wasn't anything on the solid JS side of things. So I just kind of went with it and it helps. I get this great story behind it. I even have the tattoo on my arm and... 

CHARLES MAX_WOOD: Oh wow. 

STEVE_EDWARDS: You know, for those who this is the audio podcast, he's showing us the tattoo on his arm in the video. Yeah. 

AJ_ONEAL: Unfortunately, I was not able to discern it. The video was a little too fuzzy for me. 

STEVE_EDWARDS: So Ryan, real quick, what are the other two hard things in computer science besides naming things?What was it? 

RYAN_CARNIATO: Caching and off by one errors. Right? Yeah. Yeah. That's right. Those are the two hardest things. Yeah, definitely. So yeah, it's been quite a journey to be fair. I, I wasn't ever expecting much of anything from it. So, you know, when the comparisons come up to react and whatnot, I'm always kind of surprised and I feel like I have to sometimes step in myself and correct people. There's been a lot of these narratives going around solid. It's not react and it looks a bit like react. And it's intentional, yet it's also wasn't, it wasn't because I was trying to like undermine React. It was just, it just, we, you know, we ended up where we ended up. And I hope that when people go and they look at it, they can see past React, which I know it's a, it's a big ask, but like, honestly, like even today, it's like, I don't want to make a new templating language. JSX does like majority of what I'd want. I mean, there might be a couple of places that I'd prefer things to be improved, maybe a little bit more structured. Maybe JSX 2 would be good, but the effort that goes into supporting types, that goes into templating, syntax highlighting, prettier, like there's a whole world, language server stuff, like there's a whole world that you would end up taking on when you go there. And we use JSX in an unorthodox way. So I can understand how it's sort of not JSX in other sense. It's not just TypeScript. It does put us on this line because even though we get to leverage most of the tooling for the syntaxual level, like the way things look, like even TypeScript for JSX, we get to completely leverage. It's just a freebie. We don't get to leverage other things. Like if a library decides that we are agnostic because we target JSX, it doesn't work with Solid. If the DOM or sort of the web decides that they're going to add JSX to the standard, it's not going to help Solid. In fact, it's probably going to make things worse because then there's going to be a confusion there about what the expectation is. I do see that. I mean, this has been a very pragmatic approach to how I do things. And obviously with more people joining the community, more ecosystem, more work being done, then there's more capability and more things that can be done. But for the meanwhile, I like keeping things pragmatic using what we have and just leveraging it as much as we can. 

CHARLES MAX_WOOD: Cool. All right. Well, let's go ahead and move over to PIX. 

 

Hey folks, if you love this podcast and would like to support the show or If you wish you could listen without the sponsorship messages, then you're in luck. We're setting up new premium podcast feeds where you can get all of the episodes released after Christmas 2020 without the ads. Signing up will help us pay for editing and production. And you can go sign up at devchat.tv slash premium. 

 

CHARLES MAX_WOOD: AJ, do you want to start us off with picks? 

AJ_ONEAL: Oh, let's see. I've been pretty weak on the picks the last few episodes. Let me see if I can return to my former glory of big pick status. No, no, not really. So what I would say is I've been watching, they rebranded it six different times. The latest iteration, I think is called talks at Google. I've been watching some of those and I'm pretty satisfied with the ones that have popped up. I really like learning from people that have lots of experience in the industry and that really consider software engineering as a craft, not just programming, but actual engineering. And I just can't recommend enough that people watch those types of videos that are about the systematic approach to producing correct outcomes in code. And, you know, as I always say, creeds of craftsmanship.com is  craftsmanship.com, feel free to make a recommendation there and check out the growing list. I, it's called creeds of craftsmanship because it has Also, the various creeds are right up at the top, such as the Zen of Python, the Go Proverbs, Dry Wet Naha, the Agile Manifesto, 12 Factor App, Laws of UX, Rails Doctrine, Pretty Rational, Testing Trophy. So yeah, I'm going to pick that. And then if you want to follow, I'm doing live streams almost every day on YouTube and Twitch as Coolage86. And then...the more structured content and the better clips that come out of that. Cause these live streams, I'm just doing code, right? So I'm going four hours, six hours, a little short one might be two hours long. Uh, but then I tried to do some more structured content and I put that at underscore beyond code on Twitter and beyond code bootcamp on, on YouTube. So if you're interested in that, yeah, check it out. 

CHARLES MAX_WOOD: Good deal. Steve, what are your picks? 

STEVE_EDWARDS: Yes, we've come to the high point of the podcast with the dad jokes.

CHARLES MAX_WOOD: Unfortunately, I already did some of those. 

STEVE_EDWARDS: Yes, but you can never have too many. So recently, you know, I got a little parking ticket because I parked in the wrong place. And I went to court for it and actually and entered a plea of insanity. And I said, your honor, who in their right mind would park in the passing lane? And yesterday, by accident, eight o'clock, it was very time consuming, especially when I went back for seconds. And then along, since AJ likes educating people, did you know, here's a little known fun fact, before the crowbar was invented, crows simply drank at home. Thank you. I think I see AJ cursing me out with his mic. 

AJ_ONEAL: No, I wasn't, I wasn't fast enough on the unmute. 

STEVE_EDWARDS: Oh, okay. 

AJ_ONEAL: Cause I'm using push to talk right now and I had another window selected by mistake. But that one, that was a good one. That one goes. You know, a solid A. I'll get it. 

STEVE_EDWARDS: Thank you. Anyway, those are my picks. 

CHARLES MAX_WOOD: All right. I'm going to jump in with my picks. I always do a board game pick. This one is a board-and-dice game. It's mostly focused on the dice. It's called dice forge and effectively what you do is you, you have these dice that have different dice faces that you can snap into them and I'm trying to pull it board game geek at the same time. So anyway, you.roll the dice, you get gold and you get these other tokens, and then you can spend those tokens to get cards, and then the cards give you dice faces, or you can just buy the dice faces with gold. And anyway, we really have enjoyed playing it. We have one of the expansions as well. So I don't remember if last time I talked about Board Game Geek, but Board Game Geek is a website where they have a bunch of information about games. It's basically a big directory of board games. And they have a weight. I didn't realize this was a thing until last week, but you can go and you can look and see how the game kind of ranks out with the other game. So on a scale of one to five, this one has a weight of 1.96. So it's almost a two. That means that it's not, it's a little complicated, but not terribly complicated. I don't think I picked it last time. So I'm just going to fill people in here for a minute, just to give you an idea. So monopoly, for example, if I look at monopoly on here it has a weight of 1.64, so this is slightly more complex than Monopoly. Settlers of Catan, that's always a bad one to look up because they've got a million versions of it. Settlers of Catan... Yeah, they've got a bunch of different editions and stuff in here that was a bad one to pick. But if you do like Ticket to Ride, for example, that one's a 1.84, right? So anyway, you kind of get the idea. Some of the other games I've picked are like a 3 or a 3.5, so they're much more involved. But this one is...Yeah, it kind of clocks in there. The game I picked last time, Taco Cat Goat Cheese Pizza, I think clocked in at about a one. Yeah, it's a 1.03. So just to give you an idea, right? So if you're not into the really involved games, then you want to stay at the one or two level. So Dice Forge is right in there. If you really do like the more involved games, then you can rank up. So like Seven Wonders is a 2.3, right? So that's probably on the edge of what most...casual gamers are going to want to go for and then if you're way into board games, you'll pick other ones. But board game geeks also has forums. So some of the games that we've played that I've really enjoyed or that my family has enjoyed, sometimes after they publish the game, it becomes apparent that you can kind of read things two different ways, right? When you play a card or something like that. And so a lot of times they'll have clarifications in the rules. And so as we play, sometimes it's like, well, does it mean this or does it mean that? And sometimes it seems it'd be more obvious to be this and that, and sometimes it's just not that way. And so then we'll go look on BoardGameGeek and see if they have a clarifications thread on the forum. So anyway, I'm going to pick BoardGameGeek.com and DiceForge. And then a few other things that I'm going to pick. I kind of had something come up this last week that has forced me to speed up my timeline as far as getting dates out for the summits. So if you're looking for JS RemoteConf...which is an online conference for JavaScript that I did. I did one in 2020. I've done like four or five of them in other years and I've done them for other communities as well for some of the other shows that we have. Um, effectively what happened was, uh, David Heinemeyer Hansen got uninvited to do the keynote at RailsConf cause some of the organizers don't like some of the things he says online. Frankly, I think as long as he comes and sticks to Rails, I don't see a big problem with having him speak, so he's going to be doing our Rails. Summit in August. But get together people who love code, come and do code, right? So anyway, so keep an eye out for that. Go to topendevs.com slash conferences to find out more about the other conferences we have coming. I'm going to do a JavaScript one probably May or June. And then we're probably going to be doing like a React one because we have a React podcast. I'm planning to do at least one for each show that we have that we're currently producing. And anyway, so keep an eye out for that. We'll also be doing one for Vue and one for Angular because we have shows on those as well, DevOps, you get the idea. But yeah, the Rails one will be in August. So anyway, those are my picks. Ryan, what picks do you have? 

RYAN_CARNIATO: Yeah, I'm always looking at new technology in terms of the website on JavaScript, JavaScript frameworks, I'm always bleeding edge. Every time a new framework enters a benchmark, I'm like, they're looking at what they're doing and I'm always interested. And this week, a new framework came out and it's a different kind, it's kind of more of on the Alpine JS and petite view side where the idea is to enhance existing HTML, essentially, that maybe was built with a Rails backend or something else, which makes a little different. It's called CoreSet, actually, coreset.dev. And what it does is it uses CSS style syntax to add data binding on top of existing HTML. Really interesting take. I've never seen anyone do this before. And if you just want to see something kind of a little bit different, a way of approaching it, I think it'd be cool to kind of check out and take a look around. It's a very novel approach. It's in a slightly different space than our full declarative libraries, but it seems very capable. So I think that's something kind of worth looking at. Yeah, I think that's how I got off the top of my head. I'm very much immersed between working on frameworks at work and in my free time. So that's my pick for today. I'll just drop that. 

CHARLES MAX_WOOD: Cool. One more question. If people want to connect with you or see what's going on with you and the things you're working on. Where do they find all that stuff? 

RYAN_CARNIATO: Best way to connect with me is on, yeah, Discord. Seriously, just come to the, go to our site, click the Discord link, join us on Discord. I'm almost always available. Send me a message, ask a question in the chat, introduce yourself, that's your best bet. Otherwise, you can follow me on Twitter at RyanCarniato, and yeah, I would say that. Those are the best ways. 

CHARLES MAX_WOOD: All right, cool. We'll go ahead and wrap it up here, and until next time, folks, Max out. 

STEVE_EDWARDS: Adios.

 

Bandwidth for this segment is provided by Cashfly, the world's fastest CDN. To deliver your content fast with Cashfly, visit c-a-c-h-e-f-l-y dot com to learn more.

 

Album Art
SolidJS with Ryan Carniato - JSJ 528
0:00
53:03
Playback Speed: