Video Summary and Transcription
SolidStart is an efficient, unopinionated, and ergonomic full-stack framework that provides great defaults and flexibility. It includes features such as a bundler, a serializer, a server, and a router. The serializer, Seroval, enables streaming and real-time state synchronization between server and client. SolidStart offers powerful file routes, RPCs, and single-flight mutations. It is recommended for building UIs in full applications, Spark, single-page apps, and native apps.
1. Introduction to SolidStarts
♪♪♪ Thanks for being here. Let's talk a little bit about SolidStarts. SolidStarts is when we put a bunch of other features in Solid to make it a full-stack framework. It is efficient, unopinionated, and ergonomic. The Solid ecosystem is built around the idea of having great defaults and offering tons of flexibility. Tooling and JavaScript in web development is like LEGO bricks. We build something bigger by composing LEGO pieces. If you start gluing the LEGO pieces, it spoils the fun. SolidStars avoids that by providing great defaults and flexibility.
♪♪♪ Thanks for being here. Thanks, Phil, for the introduction. And, yeah, I've been in Europe for some time. I stopped counting after the first decade. So, yeah, let's talk a little bit about SolidStarts. Some of you, I hope, I imagine most of you have been in the keynote today where Ryan talked a lot about the challenges of front-end development nowadays, and you probably wondered how a guy that has those ideas would come up with a framework. So, let's talk about it a little bit.
But first of all, yeah, Attila or Achla or whatever rolls off your tongue, if I understand you are talking to me, I'll reply, I promise. I work as a DevRel lead at a company called Crab Nebula. We worked with another framework called Tauri, which is a framework for building hybrid applications, and we do think it has a really good combo with Solid. So, I also work with Solid on a day-to-day basis. I'm part of the Solid DX team, and I'm a GDE. So, if you have any feedback, questions, anything, you can use this handy shortcuts on my website, because naming things in the web is hard, and I just switch handlers everywhere. So, just append a social network and you'll find me, and I promise I'll reply.
But, yeah, without further ado, what the heck is SolidStarts? So, you heard Ryan talking about and you probably know him as a Solid creator. So, SolidStarts is essentially when we put a bunch of other features in Solid to make it a full-stack framework. And the idea is to be efficient, unopinionated, and ergonomic. So, a Solid framework, I would say, because of that whole point that he had when he said that he wanted to build a SolidStarts, a meta-framework that hates meta-frameworks. So, as a DX team member, part of my work is take these nuggets of knowledge, pain, and suffering that he has, and translate that into how that imprints the vision of the tool itself. So, a lot of the slides in this talk are about going deeper into what does that actually mean.
So, first, who here likes LEGO? I love LEGO. I hope you appreciate the analogy. So, yeah, tooling and JavaScript and web development, I'd say, is like LEGO bricks. We go composing things and they don't do much on their own. Hopefully, if they do too much, it's probably a problem. But when they do, they have a bunch of nice features and then we put them together and we build something bigger. That's our apps. And then, we come to the conclusion in the Solid team that if you start gluing the LEGO pieces, it kind of spoils the fun, because then you build something that's great for you at that time, at that period, but then, if you grow up over it, or if you change your mind, or if you see something that's cool that would fit in the middle, it's kind of hard to do it. So, we decided, no, that wouldn't be the case. So, SolidStars is built and the whole Solid ecosystem is actually built around the idea of having great defaults, giving you, like, the best possible experience from the get-go, but also offering tons of flexibility.
2. Exploring SolidStarts
So, if you don't want to use a piece of that, you can take it out and build it your own. Your opinions are welcome throughout the stack. How does an actual SolidStart app look like? SolidStart is the core of the framework, packed with a bundler, a serializer, and a server. Solid itself is the rendering library for the user interface. The router handles client-side logic and data loading, including soft navigation. The metatags package is also available. Under the hood, SolidStart is built with flexibility in mind. The serializer, Seroval, deduplicates API responses to save memory and bandwidth. It also has the capability to stream data. The first demo is the Raven website.
So, if you don't want to use a piece of that, you can take it out, and you can put whatever you want, you can build it your own. That's the idea. So, in other words, your opinions are welcome throughout the stack. Like, literally, if you don't like the router that we built, you can build your own. And it's pretty much as easy to use an external router as it is to use our own. And that works for everything, every other thing.
So, how does an actual SolidStart app look like from the distance? So, we have SolidStart, which is the core of this framework. So, SolidStart comes packed with a bundler, a serializer, and a server. Then we have Solid itself, the rendering library that is helping you render the user interface. We have the router, which is going to do the client-side logic and also the data loading. So, you can create different URLs, you can manage the state between the URLs. It's going to handle for you the soft navigation, all these kind of annoying pieces that we need to reinvent browsers. And it's also going to do the data loading part. So, giving you some nice primitives to work on. And then, like the last, the biggest unsung hero is the metatags. So, we have also a package for that. You can build your own, but, yeah, there's nothing much exciting about that.
So, yeah, but the idea is to peek under the hood of SolidStart, right? So, what builds SolidStart? And the flexibility that we actually give you. It's not really taking out the parts that integrate to it, but you can actually mess around with the internals of it. And for that, you need to understand it. So, as Ryan said in his talk, having a server between you and your client and your user is a tricky thing to have. So, for that, we have our serializer. It's called Seroval. So picture this. You have three server functions which you're doing as a best practice. You fetch data from the server and then you want to pass it to the client. What happens is that Seroval is going to take all these functions and is going to deduplicate the references, which means that if different API request comes up with the same response, we're only going to serialize that once to save you some memory on the server and to save you some traffic bandwidth as well. On top of that, because everything in the web is very naturally asynchronous, what Seroval also has a capability for is to stream data, which brings us to the first demo. So, our first demo is this little website called the Raven.
3. Streaming and Seroval
Our first demo is the Raven website. It showcases the capability of streaming through the server with the help of our serializer. We use a signal to control the rendering of data, ensuring efficient list updates. The serializer, Seroval, supports various data formats and enables features like real-time state synchronization between the server and client. This streaming capability allows for powerful reconciliation and prevents race conditions. Let's now delve deeper into the core.
So, our first demo is this little website called the Raven. Can you see the network tab? Yes. So, what I'm going to do now is I'm going to kick off some streaming and this is going to line by line send me the poem, the Raven from Edgar Allen Poe. And, as I start it, you're going to see it takes a little bit and as I get one by one and please notice the request size here. It's one same request that's just been streaming through the server. This is a capability that we have thanks to our serializer.
The way it works is on the surface level, it's pretty much the same as any other request. What we do with a solid app is we create a signal then to control the stuff that we're doing and we get some data and we keep rendering it. As most of you, I imagine, are React developers we have this for which is what we use to control the list. It does a little bit extra work in terms of preventing our list to re-render every single time. So, if you see here when I refresh, if I start again, the lines just get appending. So, the line that was already there doesn't get changed or touched or anything as the line below comes in. That's why we have this for.
If you look at the poem, what I have here is Richard, the poem, as a string and then I have a promise that has a little set timeout just to create some interval on it and it's going to split the poem by any line and then the generator is just going to yield one line at a time every 500 milliseconds. There's nothing that big that I can do that I need to do for that. The serializer supports synchro generators. It supports readable streams. It supports promises. So, it's just out of the hood. That's what we mean with great defaults for having an awesome user experience.
We talked about Seroval which is a serializer which is arguably the most complicated part, the part that messes you up because we then need to prepare data to cross the boundary between the server and the client. So, that's what we do. The idea of Seroval is actually being able to support this kind of stuff, like, not because we want you all to send poems to your users, though that might be nice at some occasion, but also because these actually enables a bunch of awesome features, like, as Ryan mentioned in his talk, when you have, like, most all frameworks actually have a gigantic manifesto in their client side apps and this kind of stuff. This kind of streaming is going to unlock for the future where you can perhaps, hopefully, one day we can have the client being aware of the state on the server and that allows for a very powerful reconciliation and prevents a bunch of race conditions that are, to this point, inherent to every kind of server components. Every kind of partial rendering has a problem where you have difficulty aligning the state you have on the server while the user is interacting with the state you have on the client side. The user is interacting with the state you have on the server while you're rendering stuff. So, the streaming capability allows us to do that because it allows the framework itself to sustain a permanent connection between the server and the client, if that's needed. Okay. So, we go a little bit deeper. Now we split the core.
4. Core, Config, and User Interface
Our core is built on top of the open source community, utilizing Vinci as a bundler and server runtime. Nitro, the server runtime, allows for deployment to various platforms with its presets. Vite is integrated to enable bundle splitting between server and client code. Solid start config offers flexibility in middleware, pre-rendering, link handling, and path configuration. On the user interface side, we have solid routers that provide data loading capabilities and options for file system and cache customization.
We have the serializer and the core is actually built on top of the open source community. One of our core members created this package called Vinci. So Vinci is actually a bundler and a server runtime because we picked Nitro, which is the server runtime that Nuxt uses, that Analog uses. It's a very powerful one. Think about it as Vite but for servers. So it bundles up a server runtime, a Node.js server runtime, not really a Node.js, it actually can run on the Edge and Deno. So it packs up a runtime and the bundler.
So Nitro itself has Vite inside so it's like a kind of inception kind of thing, but we then are able to have a very resilient runtime, which means that out of the box, solid starts through Nitro can deploy to any platform that, like, we have about 25 presets already, so with one string change, you can deploy to CloudFlare, AWS, even Nuxt Hub, a bunch of stuff. And we also have Vite there because then it allows us to have this use server directive so we can do some bundle splitting and make sure that some code belongs to the server and some code belongs to the client. So that's Vinty and as I mentioned, good defaults, tons of flexibility.
So out of the box in most cases, this is what your solid start config is going to look like. You don't need it. So that's our app config and that you can do, but also you have a bunch of flexibility. As I said, you can declare a middleware, you can define pre-rendering, you can make all your links to be crawled and pre-rendered during runtime. You can ignore, you can make sure that your build is going to fail if a link is a 404. And you can set some paths. In this case, it's actually straight out of our docs website because we have some snippets that look too much like real code and then it was causing some 404s on the pre-rendering, it was confusing Nitro, so we did that. You can set some extensions and solid start Vinty and solid start are going to surface the whole VIT config for you. So you can do as you would in any VIT app and add packages, like we have virtual modules, we have all kinds of crazy stuff in our docs. And you can declare the middleware. I'm not going to talk that much about it, but yeah.
And then on the user interface, we have solid. So through solid routers, solid actually gives you some nice capabilities for data loading. So the data loading looks like this. We have created a sink, which is our signal for async transformations. And you can define that your route is going to preload by just exporting a variable. That means that you're going to give some hints to your server run time, so then things can get reloaded and that actually unlocks something pretty cool that I'm going to show you in a second. Besides that, solid router is going to expose to you a file route, where you can define which file system you want to use, which rector you want to use to create the file routes. We already saw the export routes, and the create async, but then we also have a cache. So you can actually define the duplication cache for your RPCs without us doing it under the hood, without us changing any prototypes.
5. File Routes, RPCs, and Single-Flight Mutations
You can define a key and use a helper for creating server actions. File routes in Solid Start are powerful and allow for parameterized routes, named routes, index routes, cache routes, and named index routes. RPCs in Solid Start involve server functions that hit an external API, with the option to wrap them in a cache for deduplication. Servo stores references and deduplicates artifacts, enabling single-flight mutations by returning new page data with response redirects.
You can just define a key and that's it. And you have a helpful helper for creating server actions that I'm going to show you in a minute.
The file routes is actually quite powerful and works as you would expect. You define the route directory. You can have parameterized routes. You can have a named route. You can have the index routes, you have cache routes with parameters, and you can have a named index route. So if it's between parentheses, we're going to ignore that and that's going to be the index route. I think Remix and Nuxt do exactly the same way.
To recap, this is what an RPC looks like. This is what a data fetching would look like ideally in Solid Start. So you have a bunch of server functions that are going to hit an external API. Before hitting the API, if you wrap them into the cache, they're going to deduplicate through a cache key and then the cache is going to request only once to the API. So you save one. And then this is the special thing that as far as I know, Servo is the only one doing. It's going to store references for every artifact that you get on the same flight and deduplicate them. So you only serialize stuff once while they're the same. So with that, it allows us to do something that's really, really cool that I'm going to show you. You can, whenever you're doing a mutation on the server, you can return the new page data with the response redirect. That's what we call single-flight mutations. So let's have another demo. Yeah, so not this one. This one. So this is my little app with a demo that I stole from my friend Daniel. And I'm just showing up a few cards of Pokemon. And traditionally, you would come and say, yeah, let's create a Pokemon. Let's create Josh. And I'm going to name it, yeah, I'm going to give it a little image. And then we're going to have the, let's take a look at how it works normally.
6. Single Flight Mutations and Preloading Data
With single flight mutations, you can define a route that loads all your Pokemons and preloads the data. By augmenting the form with a server action and passing an add Pokemon, you can replace the on submit function. The server action is a wrapper around an asynchronous data call that throws a redirect once done, resulting in only one request in the network tab.
And then we're going to have the, let's take a look at how it works normally. So I create Josh here and then we have over here, we have two requests. The first one is going to be sending the mutation to the server and then it's going to trigger the redirect and then I get the payload with the whole thing, right? As one would expect.
In this case, this is what we have. So I have my server. As usual, on submit, I send the form and then I add some stuff. When the response comes back, I send them back to the root, right? So nothing too magical. I am not playing around. So my just add is running on the server and then I'm doing some database stuff there and that's it. Normal, right? That's usually what you would do.
But then with single flight mutations, we can then define a route and we say, okay, so this route is actually going to load all my Pokemons. So then solid start is aware that whenever this route is going to get hit, they need to preload this data. And that's about it in this case. And then on my single one, I have this form and then I'm going to augment this form with my server action and then I'm going to pass an add Pokemon. That's just lit. I just replace the on submit with that thing. And then on my Pokemons, instead of the just add, then I'm going to create a server action. The server action, this one, is just like a wrapper that's going to go around my asynchronous data call. Pretty much the same. The logic is exactly the same. But then once everything is done, I'm just going to throw a redirect. And because I'm doing this, I can come over here. Let's clean this up. And I come to the single add and now I'm going to add the Alex Pokemon and then let's I think that's Charizard. Okay. And then once I add it, look at my network tab. I have only one request. So my post request already came back with the data for the whole thing out of the box. And these are single flight mutations. For this example, it's not that mind blowing.
7. Data Heavy Operations and Solid Start Framework
Imagine having a data heavy operation going to the server multiple times. Solid Start provides awesome primitives, good defaults, and flexibility to build on top of open source. Connect with me on Twitter or YouTube for more information.
But imagine if you have a data heavy thing going to the server multiple times. It can be pretty awesome. It can save you a lot of run times if you have big latency and stuff like that.
I'm running out of time. So let's recap. The idea of Solid Start is having awesome primitives, good defaults, allowing flexibility and building on top of open source. So that's what we mean with a framework, MetaFramework that hates MetaFrameworks, is allowing you to break out of it and trying to build on top of giant shoulders of giants.
Thank you very much for having me. If you want to talk to me, you can find me on Twitter or YouTube. That's usually where I'm there. My YouTube channel has been through a years, but I'm going to start recording some stuff on Solid Start and Solid and Tauri on July. And you can find me the whole day in the hallway track. Thank you, guys.
Using Solid Start with React and API Calls
Solid Start cannot be used with React instead of Solid due to their different rendering models. However, you can compose them together and try it out. The framework focuses on providing rendering and data for the client user without full page reload. Different API calls can return the same responses, but the framework ensures that all the rendering and data are provided to the client user.
First one, which I think is, I guess, relevant. I guess sort of relevant for being here at React Summit. Asks, can Solid Start be used with React instead of Solid? Oh, okay. So the short answer would be probably no. The long answer is you could possibly try. I don't know. As I mentioned, it's composable. I heard about people on migration having Solid and React running side by side. I would say that's kind of complicated in the long run, because they have very different rendering models. You might find yourself a lot of foot guns there, but yeah. And then there was a bit of a follow up, which is just, would there be any plans for that to be officially supported in the future? Probably not. Yeah, no. I think Solid Start, as a first class citizen, it's going to be solid. But yeah, as I mentioned, you can compose the way you want. I'd be interested to see it. If anybody wants to do it. Give it a go. See what you can manage with it. Awesome.
Okay. Can the client trigger a stream start without a full page reload? So for example, that's to refresh data that's on the UI periodically. Yeah, so that one wasn't doing any full page reload with the stream. So that was just changing a little signal, and that would immediately send a regular fetch request, and the response would be automatically appended there. So no full page reload. Excellent.
Okay, so this question came in fairly early, so I think it was maybe when you were talking about API calls and things like that. And somebody's asked, how do different API calls return the same responses? Is that a valid use case? So they would return different responses. So what happens is that the polls, they don't return different responses. It's just that the response for the API is the same. What the framework is doing is giving you all the rendering, all the data that you want to render in the same goal, to your client user.
Handling Different API Responses
APIs can return different responses to the same request based on data updates over time. When handling authentication, different responses may be received depending on the outcome, such as redirects or forbidden access.
It's not that the API is giving you a different response in this case. Yeah, okay. And I guess like, in general, APIs can return different responses to the same request, but data updates over time, but... Yeah. So if you're going to Auth, if you're doing Auth, for example, and then if you have the happy path, you can log in, it's going to redirect you to one place. If you don't, it's going to redirect you back to another place. Technically they are different responses, or forbidden, or something like that. Right, yeah, different header as well.
Solid Start Framework and Misunderstood Feature
Charizard is number six, not number five. People should make decisions based on benchmarks rather than influencers' opinions. Frameworks and meta-frameworks drive innovation. SolidCore was pleased when Vue announced Vapor and Zvelt announced Runes. The most misunderstood feature of Solid Start is that it's not ready for production.
This got voted up quickly, how did you not know that Charizard is number six, not number five? Huh? What? Charizard. Ah. That's nice. What's Charmeleon? Charmeleon, thank you everyone. So, yeah, I was just like, I was testing this demo a lot, and I don't know, I just really don't know, I was just at some point trying to memorize some numbers to be funny. I don't even remember if I got them right, to be honest.
256 was way up, I don't know. This is a big question, here's a big question. Will there ever be a definitive meta-framework in the JavaScript world? I hope not, actually, because I do like a lot the plurality. What I do hope for the future, though, is that people look at benchmarks and make good decisions. I see a lot of people going with influencers' opinions, sort of, in terms of, oh, this guy likes this one, and he's awesome, so he's probably right. I think that each framework optimizes for a specific use case, and that's awesome. So what I hope for the future is that people don't try to measure a turtle by their ability of climbing a tree. So yeah, this kind of stuff is what I would like to do. Competition between frameworks and meta-frameworks and everything, browsers, whatever, all that competition actually just drives innovation in these things. We learn a lot from each other. So one of the things we were super happy inside SolidCore was when Vue announced Vapor and Zvelt announced Runes, and they got pretty much the same model as Solid 1.0 has. And we were like, OK, that's awesome. That means we're on the right path, because all these clever guys are saying we are. So that's awesome, too. It's kind of reassuring. So we do like that. We do like this exchange. That's why we are in a React conference, actually. It's not to convince you to do anything or migrate or whatever, it's to learn from each and every one of you. Fantastic. That's awesome. That's awesome.
All right. What do you think is the most misunderstood feature of Solid Start? So the most misunderstood feature in Solid Start, so I think, I wouldn't say a feature, but the biggest misunderstanding around Solid Start, and I actually saw this question in Ryan's talk, is that it's not ready for production.
Benefits and Origin of Solid Start
Solid Start provides a variety of solutions and libraries for building UIs. It is recommended to use Solid Start for full applications, even for native apps. The development of Solid Start was influenced by three years of research and careful consideration for the API.
Or that the ecosystem is too small. Or that we don't have solutions. We actually have a bunch of those. We have, like, you all like Chats Yen, right? I love it, too. We have Solid UI, which is exactly a port. Radix UI is amazing. We have Corvo and Cobalt. They're awesome. I can actually build full UIs without missing the gigantic React, because I was a React developer, I don't miss the gigantic ecosystem that React has, because we do have tons of solutions for Solid at this point already. Nice. Yeah. Don't sleep on this.
All right. Well, I think this kind of is a good follow-up as well, then. Do you recommend building a full application with Solid Start, or use the server as a backend for frontend and a separate full extra backend? I do recommend building Solid Start, because that's what I do. We have at Crab Nebula, we have two apps in production. And both of them use, like, one of them is a Solid SPA, and a Atari app with Solid. So we built, like, a native app with Solid. And the other one is actually a full stack application that's using Solid. We started it before Solid Start came out, but we are using a lot of Solid Start stuff as well. So I do recommend it. Since it hit 1.0, there's no reason not to. And did building the app that started before Solid Start exist, like, kind of feed into how Solid Start was built as well? I wouldn't, like, the most, like, I'm not part of the core. So a lot of what I can do is give very passionate feedback about stuff that break on me, or that I think is awesome. But I would say that Solid Start itself went through three years of research. So Ryan was pretty, like, as you saw, he hates meta-frameworks. He was pretty focused on landing an API that he would not hate. So he went back and forth a lot. He's very careful about reaching 1.0. So I would say once he did that, he is confident he found the best stuff for Solid Start.
Solid Start for Spark and Native Apps
Solid Start can be used for Spark, single-page apps, and native apps. With a simple preset change, you can swap between different modes. Tauri, along with SolidJS and Tailwind, offers a smooth development experience for building sample and personal apps. It supports all desktop and mobile platforms. Feel free to reach out for the link and share your feedback.
That's awesome. There was a question that said, can I use Solid Start for Spark, for a single-page app too? But I think you just answered that. You can. So yeah, so there is, it's just a preset change. You can change a mode. So you can actually swap between them. That's what we do at Crab Nebula. We have, like, some app configs, which are the VITs. And you can swap, and then because Tauri doesn't have a node runtime, so you can swap it out and then back. Very nice.
Actually, yeah, there's an extra one asking about, like, native apps as well. Would you ever want an equivalent to Expo or React Native for native apps? But if you already do it in Tauri, is that... Yeah, so we do Tauri. And I'm building, like, I have this template that I'm building called Quantum, which I use SolidJS and Tauri and Tailwind, like, all together, and I put a bunch of niceties and opinionated stuff that I want to have there for my sample apps and my personal apps. It is quite a nice experience. It can build for all desktop platforms and all the mobile platforms. So it's pretty decent. Like, tweet at me, and I'll send you a link, and I want to hear your feedback.
Awesome. Well, that's time we have for questions. Awesome. Thank you so much, Attila. Let's give another round of applause to Attila. Thank you.
Comments