Skip to main content
984

March 4th, 2026 ×

How to Make a DOM Library Render Anything w/ Paolo Ricciuti

or
Topic 0 00:00

Transcript

Wes Bos

Real quick before we get going, we are launching a new video series called March Mad CSS. It's a CSS battle tournament with 16 of the world's best developers.

Wes Bos

Josh Komu, Chris Coyer, Adam Wathan of Tailwind, Cassidy Williams, even Scott and I. Now we have a ton of prizes to give away. And if you want to win, go to madcss.com, and you're gonna fill out the bracket. So madcss.com, log in with your GitHub, and you're gonna pick who you think is going to win each of these. And whoever gets the highest score is going to win this amazing prize pack. Like this. Sick CSS jacket. You can also order this from the website as well. We got some pretty cool merch, some tees, stickers, and Node Jean, first, second, third prize. Go to mad CSS. Make your picks. You can share them with your friends. You'll probably win. Peace. Welcome

Scott Tolinski

to Syntax Today. We have a really awesome guest on.

Scott Tolinski

Paolo Ricciutti is going to be talking about Svelte custom renderers and how how the Svelte team is basically going to be taking a library that is entirely focused on the DOM and really putting it into a a a universe where, well, you can, like, render anything with it. So there's a lot that comes from that both in strategy, but also in what that enables for developers who might be considering using this tool. And, Yeah. I'm really excited about this. So welcome to Syntax, Paolo.

Guest 2

Hi. Welcome.

Guest 2

I mean, not welcome.

Guest 2

Thank you for the welcome.

Scott Tolinski

Of course. Yeah. Yeah. Do do we first meet in Barcelona? That's where we met,

Guest 2

somewhat recently. Right? Yeah. We met in Barcelona

Scott Tolinski

personally. Yeah. The Svelte Summit was a a a great hang there. You're at a a company called Main Matter. What what is it that you're you're doing, and and what's your relationship to the Svelte project overall?

Guest 2

I lead the Svelte team at Main Matter. Main Matter is a consultancy.

Guest 2

We do a lot of Svelte. We do Rust.

Guest 2

We do Amber.

Guest 2

Like, it's it's it's basically a sort of an top tier, consultancy. Like, we we we're not just, executors.

Guest 2

Like, we actually help you architect your your solution.

Guest 2

We help you hire even, like, it's more, like, on a high Vercel, But we also do feature development and stuff like that. And, basically, I am the Zwelt expert there. And the reason why I am the Zwelt expert there is because I'm very tied to this Zwelt project. I'm one of the maintainer of this wealth project. I also I started as a wealth ambassador JS Scott, which is basically, like, people that won't shut up about wealth. And so Yeah.

Scott Tolinski

Yeah. That's me. Right? That defines me, I think. Yeah.

Wes Bos

Sometimes we have to shut them up about it, but, it's all

Scott Tolinski

all good stuff here. How did you find yourself in Svelte specifically? Did you do other frameworks before then? Like and you actually just recently published a a blog post about why you chose Svelte. I don't know if you wanna get into some of that. Just today, we published a blog post about why I choose I choose, and I continue to choose Svelte. And you can check it out on mainmatter.com

Guest 2

if you want on the blog post.

Guest 2

But, yeah, in general, I'm I started with React, really. And, like, nice thing, by the way, like, my first approach ever to React was watching CJE doing the thing with React.

Guest 2

Yeah. And I still remember, like, I was taking my COVID vaccine for, like, in 2020.

Guest 2

And, generally, I am a huge nerd in in real life. So, like, I tend to, like, watch syntax or watch conferences even in my, like, off time. And so while I was waiting for to take a shot, vaccine shot, I was redeeming reactivity by Rich.

Guest 2

Yeah. I literally fell in love with Svelte because, like, the idea of using a compiler to, like, ease the burden on on the browser is something that, like, the moment, like, he mentioned it, I said, like, why nobody else thought about this? Because it felt so obvious to me.

Guest 2

And, like, from there on, I started using Svelte for some side project just for fun.

Guest 2

I started learning Svelte just for fun, and then I started using it. I also participated, together with Antonio Sarcevic.

Guest 2

We teamed up and we built Svelte Lab, which is like a a a Stackblitz like specifically for SvelteKit, and we won the Sanity that. And then this basically got me, even more into the Svelte word. I became a Svelte ambassador, and from there, like, it's just it's just threefold. Like, I for example, I am also the maintainer of the Blue Sky feed for Zwelt. So I I generally tend to joke that if it has the words Zwelt in it, I'm probably somewhat involved in that. Yeah. Yeah. Yeah. I you you've been, like, a really positive,

Scott Tolinski

force in the Svelte ecosystem.

Scott Tolinski

I I think that it would be cur or it'd be interesting for the audience to know, like, how do you go from being somebody who's just, like like you said, an ambassador or somebody who's now actually working on the project?

Guest 2

Yeah. So, like, the reason why I started contributing, I always want like, in general, I love open source. So I I always did a lot of open source. Be it, like, I don't Node, I want to create a new library because I have that need, and I want other people to share the same like, I don't want other people to feel the same need, so I create a library for it. So I always been very open source. And so when, they were working on, the rewrite to the five, they shared the, like, initial draft of the five with the ambassador team because the ambassadors are basically, like it's the first step of validation for some API. So, like, the first thing that we generally do is that, like, we build some API and then we, like, let ambassador critique that API so that we get some initial feedback. And so when I was an ambassador, I got some, like, access to to the initial draft of the Svelte five repo.

Guest 2

And, like, a few years ago, just for fun, I started building a reactivity system with signals. And so I knew a bit about signals, and I said, this is a good moment to start contributing to this belt.

Guest 2

And so, like, beat, like, a more, like, circle like, a small circle of people watching the the contributions and stuff like that. I said, okay. I'll I'll start to contribute to that. I also was very interested in learning, like, how the whole, like, abstract syntax three, the warp like, the compiler work worked.

Guest 2

And so I started to contribute to that. Then the repo went public, and I continued to contribute.

Guest 2

And the main motivation was I really want to, like, ease the experience for the for the maintainers to let them focus on the things that really mattered. And so I started to pick up some small issues, and then I started to pick up some more difficult issues and then more and more and more. And then in the end, like, they really didn't want me in the maintainer, but I was too much of a presence.

Scott Tolinski

Wes, how do you feel about the like, how do you feel about, like, I I get so intimidated when I like, I I've used Svelte, like, daily since, version three. I am a huge fan of the project. I follow along, like, the issues and all this stuff, and I would still have major imposter syndrome feeling like like trying to commit to it. For some reason, I I got a huge blockage there. Do you feel like that too? Like, would you commit to React or or any of these big projects?

Wes Bos

I I don't know that I would commit to React because so much of what they do is, like, planned out and it's being worked on somebody full time. But, like like, larger projects that simply just need the help, absolutely. Yeah. I I think in in most cases, if it's needed, why Scott? You know? Kinda go for it, especially if they have, like you can kinda get the vibe from a repo whether or not they're they're actively searching for people to help them out. So, yeah, go for it. That's that's how, like, everybody's story goes. Right? Like,

Guest 2

Paulo's story is like that. Just go for it. Yeah. But also, like, it's way less like, if you start, it's way less intimidating than than it might seem. Like Yeah. The moment you start getting familiar with the code Bos and you actually start getting familiar with the code base even before committing code. Like, if you live in the issue tracker, like, you will see other managers talking about, oh, we can do this and we can do this other thing and we can do this. And once you start seeing this, you start to get yourself familiar with the code Bos.

Guest 2

And then at that point, it's really just a matter of and I would say, nowadays, with AI, it's even simpler because, like, you literally get, like, a very capable engineers that you can just even ask questions. Like, you can just say, hey. How does Svelte handles, like, the parsing in this file? And it will Yeah.

Guest 2

Stuff for you, and you can just say, okay. That's now I want to try to do it. And so Yeah. You can get up to speed real quick. Yeah. Really helpful for me when I was working on the Deno Svelte bindings because

Scott Tolinski

the state there was, like, way more complex usage of the the Svelte reactivity, APIs than I was used to in normal UI code. So, like, I really need to dive quite a bit deeper into that stuff, building that the zero bindings.

Scott Tolinski

So first of all, let's talk custom renderers. For people who who don't use Svelte, who've never they don't they might not know how it differs from React.

Scott Tolinski

Yeah. Can you give, like, an overview about, like, how does Svelte use the DOM, as opposed to, like, the virtual DOM? And then two, we can get into, like, what makes that challenging for custom renderers and and and go from there. So

Guest 2

I I guess the the main point is that React really is just a different library. So, like, I think, like, this is pretty common knowledge at this point, but, basically, like, React itself does not concern with anything related to the DOM. So, like, they have the virtual DOM, and it's just saying, like, hey.

Guest 2

Create this element and, like, switch these, attribute on and off or change the value of the children of this of this thing. Thing. And then ReactDOM is the thing that actually says, okay.

Guest 2

This is how you switch, an attribute of on the DOM.

Guest 2

And this is basically what allowed React to do stuff like ink or stuff like React Native because, the different algorithm, which is what React is, is doing the different algorithm, and then it's communicating with the virtual DOM. Like, the Vercel DOM is communicating with ink or with React DOM or with React Native.

Guest 2

And each one of these renderers, I think React, they are called reconciliator.

Guest 2

It's like has the knowledge about how to actually apply an attribute, how to actually remove a children, how to actually append the children

Wes Bos

in their own word. So let let let me say for the audience really quickly, they might be wondering, like, what what is Ink? Ink JS, like, React for terminal UIs. React Native is obviously React for native mobile UIs. You might not know this, but Raycast, the the app that we use, is is built in React, and they're not running browser or anything like that. It's it's they've built their own reconciler that Yeah. That run if you build a if you build a Raycast app, you're just using React components. You're using Raycast tags. And then what happens is that, like, you can you can build a React app, but it actually renders out to native whatever. Right? And it's it's you can't just go ahead and use CSS or or HTML or anything like that in there. You have to use, like, the blessed tags that they've given you. But there's just so many different instances where

Guest 2

React is used as a renderer to something else. So, like, the difference is that Svelte, like, famously, like, when, like, Rich, like, presented Svelte, Svelte does not use, virtual DOM. Now Svelte four and Svelte three was literally basically baking in the reactivity within, like, the compiled output.

Guest 2

But even nowadays, that's about five. It's using, like, runtime reactivity with signals and stuff like that. If you take a look at the compiled output and you can do it either in the playground or there's even a command in Versus Node. Like, if you are in a component, you can use a command from the extension which is show compiled Node, and it will show you the compiled code. Like, what that Svelte component, which is, at the end of the day, just a string gets compiled too because, obviously, you are not shipping the component to the browser. So, like, the ways that works is that it takes the string, which is your component.

Guest 2

It will convert that into a JavaScript function, basically.

Guest 2

And if you take a look at the JavaScript function, it's basically interacting with the the DOM in real time. So, like, you will see stuff like get me like, dollar sign dot first child, dollar sign dot set text, which is basically spelled saying, okay.

Guest 2

I want to set the text of this element to this kind of stuff. It was always imagined as a reactivity frame like a framework for the web.

Guest 2

And so I it was never actually imagined as a replacement of, like it it it didn't have the concept of a custom renderers because it was always, okay. We want to do Wes UI. I will say, for folks, if if if you haven't messed around, I'll I'll have a link to the the Svelte dev playground. There is just a tab for JS output, and it's so readable if you wanna really understand what's going on. Actually changed a lot with Svelte five. Like, Svelte four was a lot less readable.

Guest 2

Mhmm. And, actually, one of the goal the design goal of VELT five was actually to make it much more readable.

Guest 2

And another small, like, nice thing that you can actually get from the playground, which is, like a very nice way to learn, is that since we have source maps, if you hover over something in the playground while the JS output tab is open, you can actually see which part of your Svelte component gets compiled to which part of your JavaScript file. So that that's a nice touch if you want to learn how Svelte moves stuff around, like, okay, this button that I have in my Svelte component, what it become inside my JavaScript file? As I was saying, like, does Svelte custom renderers, we had the idea of so admin matter, we love to give back to to the ecosystem that we thrive on.

Guest 2

So since we use Svelte with our clients, we also love to do open source. We even have, like, one, like, one day at a week, we can work on some open source project because we love to give back to the community.

Guest 2

And so, like, we've built some libraries. We've built, Shipdog, for example, which is, like, state management, like, library that it's basically a way to handle to juggle a sync task.

Guest 2

Once we finish that project, which, I mean, we are still maintaining it, but, like, the big part Wes, was was Deno. We said, okay. What can we do now for the Zwelt ecosystem? And it happened that during that period Wes we were looking for stuff to do for the Svelte ecosystem, a new framework came out which proposed itself as the react native alternative, which was framework agnostic. And I think you you also did a, an episode on that, which is links.

Guest 2

And one of the requirements for links for for each to be very like links, it is framework agnostic in the sense that, technically, you can literally write, an application even in a normal JavaScript file, like, with with the the element API, which is their API to create an element inside the links application.

Guest 2

And, like, it is technically amniotic, but to use it with Svelte, we needed a custom renderers. So, like, we needed a way to render a Svelte component to something that was not the Wes, because it was Node the series of a web

Scott Tolinski

browser. Available here, which that to me feels like a crazy undertaking just given how deeply rooted

Guest 2

the DOM is in Dusseld. Right? Yes. Like, it's not it's not an easy task, and that's why it's taking a while, unfortunately.

Guest 2

But, it's something that it's doable. And I actually, built a POC, for it because, again, basically, like, we started working on this, and Main Matter actually sponsored me to work on this thing for full time for three months or so. So, like, my day to day job was to work on Svelte to to build the custom render JS API.

Guest 2

And during this period of time first thing first, we had to make a change because, always talking about the JS output, in the playground.

Guest 2

If you go to the playground and write whatever component, you will see something in the compiled output, which basically like, if you have in a very simple component, like, an the input and a button that is the normal like, if you go to the playground, there is a default input plus button. If you switch to the JS output tab, you will see in on line five, var root dollar sign dot from HTML.

Guest 2

And this from HTML basically is, like, all the HTML tags in your component minus all the event listeners and stuff like that and the dynamic part. So, like, all the static part of yours that component JS a string.

Guest 2

So if you think about it, it is kinda wild, like, how can we convert from a string to actual elements? Because at the end of the day, you have to convert that string into an element, right, to actually mount it to the DOM, to add event listener to that string.

Guest 2

And the way we are doing it, it's with a very neat trick, by the way, like because I don't know if you are aware, but there is, an HTML element, which is the template HTML element. And the template HTML element, if you write a template in HTML, it will not show up on the page. So it will create the element, but then those elements are not actually appended to the page. And then you can query the template and clone the template part. And so, basically, it's a way that you can declaratively render some some HTML and then reference it in JavaScript, and you can just populate that template however you want. Like, this is a trick that you can use if you want to use, like, normal JavaScript to build your components so you can have a bunch of template in your HTML and then reference it and just fill it up with, another variable. And that's basically what we are doing. So, like, we we take the string. We give it we create a template element on the fly.

Guest 2

We set inner HTML, and then we extract that stream, like, that component, that component Yarn on the fly. Interesting. I didn't know that. I don't totally understand

Wes Bos

how it works. Like like, how are you getting from Svelte code to, like, Svelte outputs, like a paragraph tag, how does that then convert to whatever the native equivalent is on Android or iOS or or whatever other target?

Guest 2

Here, I'm just talking about, like, Svelte for the browser right now. Okay. We will get to that. I will get to that. Okay. Okay. What I was talking is that, like, in the in the browser, we do that. Like, we take your string and we pass it to the template element.

Guest 2

The template element creates that element for us, which is very fast, by the way, because it's, like, it's all done in the browser side on the browser side. So, like, you don't have to do manually create element, create target Yeah. Create tags and stuff like that. And then we just read those value. We say, like, give me the first child of this template. Give me the first child of the first child of this template and stuff like that. Now this, obviously, like, the reason why I started talking about this is because this is a huge problem because if you want to render to something that is not HTML, how do you get the templates tag? Right? So, like, you would need to ask, like, the whoever builds the links renderer to create a template tag which takes a string and returns a series of elements. Right? So that will be basically unbearable. Like, it's just impossible for for people to build custom renders this way. And so the first work that we had to do, and this is actually a PR that I worked on, during my sponsorship for, like, the the period that made matter paid for, for me to work on on, on Svelte on this.

Guest 2

And it's the fact that now you can actually generate. So if we go back to the to the JS output, tab in the playground, now there is a new option for the compiler. So we can say svelte.compile, and then you can pass fragments three.

Guest 2

And if you switch to fragments three, this is basically code.

Guest 2

Instead of using templates dot inner HTML, it's literally created. Like, it's receiving an array which has the shape, like, the h one with these children and these props. And then it's literally invoking documents dot create element, documents dot set attributes, documents dot blah blah blah. And so this was basically a required step before we could even start to think about rendering to something that was not the Wes.

Guest 2

Because without this step, you wouldn't need to create a template tag which was able to all of this for you. So, like, this was the very first step.

Guest 2

Decoupling the logic from just get a string as input to get an actual array with all the elements and all the attributes and all the all the stuff. So this was something that was also needed in Svelte because there are some CSP policies that prevent you from using inner HTML in any form or way.

Guest 2

So there were people that actually were suffering from this because they had this CSCB policies. And as long as VELT was using either it's now under the hood, it was not working for them. And so this was a nice addition like that we we took, I don't know if it's something that people say even outside Italy, but we took two pigeon with a stone. That's that's

Wes Bos

Oh, yes. Yes. Yeah. We said two birds, one stone. Two birds, one stone. Just two birds, one stone.

Scott Tolinski

I like pigeons better, though. That's fun.

Scott Tolinski

More visual.

Scott Tolinski

And if you want to see all of the errors in your application, you'll want to check out Sentry at sentry.io/syntax.

Scott Tolinski

You don't want a production application out there that, well, you have no visibility into in case something is blowing up, and you might not even know it. So head on to .io/syntax.

Scott Tolinski

Again, we've been using this tool for a long time, and it totally rules. Alright.

Guest 2

And so yeah. Basically, this was the very first step to get something going on. And then from there, we basically went like, we had two different direction that we like, two different ideas.

Guest 2

The first one was kind of a crazy one, and I actually started implementing it.

Guest 2

But we said, well, what if we like, the custom renderer so first thing first, let's talk about how will creating a custom renderer will work in Svelte.

Guest 2

So, basically, the way we need we need it to work is that you need to define some sort of module. So this can literally be a module in your project or it can be an Npm package, for example, and you will, like, expose a module from these where the renders lead. So, like, the renderer leads in this module, we import your module, and then we can use the methods that you define. So, like, you export default, create a renderer, and then you have to basically tell Svelte how to create an element in your word, how to update an attribute in your word, how to delete a children in your word, etcetera etcetera. So because, obviously, if we want to to make this very, how can I say, very, like, flexible in the sense that it's not tied to anything, we basically need to go one layer above and say, okay? We don't even know what your word is.

Guest 2

So your word could be the terminal, could be Tolinski application, could be a application. Why not? And so, you can in this way, you that creates the custom renderer can manage whatever, like, you know how to render something in your work, basically. That would effectively

Scott Tolinski

turn Svelte into something that could build terminal UIs and native apps. It's like you said, Wes throughout, for people don't know, is the three JS,

Guest 2

renderer for Svelte. The first instinct Wes, what if when you create a custom renderer, like, when you define those functions, we create a mocked version of the DOM so that then we can just pass it to Svelte, and Svelte will continue to invoke documents dot create element.

Guest 2

Mhmm. But instead of document, it will invoke the renderer if the renderer is is defined. And so, like, the first idea was we can make so that when you, like, create an element, you just return some extra information, and then we wrap your information with a DOM compatible API. So, like, we create a class, which is an HTML element like class.

Guest 2

And so that when Svelte on that element call first child, we then invoke from within that class, we invoke your your custom renderers to get the first child.

Guest 2

And this was I I actually started implementing something like this, but then I quickly realized that the DOM is just a Wes, and you can't do that because it like, there are so many quirks in the DOM, which, like, are not really immediate. Like, it's something that it's the silliest thing, for example, is that if you have an HTML element and you call text content is equal to empty string, that will actually remove all the elements inside that element from the DOM. Right? It's simple, but it means that we have to manually check, like, when you we would have to sheen text content, and then inside text content do something like, if content is empty Yeah. Yeah. And And that's probably just like one of a a thousand of these things. Yeah. Exactly. Like, it it was just too messy.

Guest 2

And so the other team that we did, and that's basically what I've built my POC on top of, is Wes what we want to do is that we want to create another runtime because, again, if we circle back to the JS output of the playground, you will see that, like, the third line is import star as dollar sign from stealth internal client.

Guest 2

Mhmm. And that is basically our API. So, like, that's stealth internal client JS all the JavaScript API that we use to interact with the DOM, to create a stateful variable, and stuff like that. And so our idea Wes, let's switch that import. And so instead of importing from Svelte internal client, we import from Svelte internal custom, and then we can build basically the same runtime, but a very simplified version of the same runtime because the client runtime actually has to do a lot of stuff, for example, for hydration. And hydration is just not a thing in the custom renderer world because Yeah. Yeah. Obviously, like, hydration makes sense if you are server side rendering an HTML page. It doesn't make sense if you are building a native app, for example, or if you are building to the canvas, Bos example. Like, there's no such thing as hydration.

Guest 2

So we could remove all that Yarn. But also the internal runtime is using a lot of these HTML DOM quirks to make Svelte as fast as possible.

Guest 2

So as I Wes saying, like, setting text content is equal to empty string to to an element, it's the fastest way to remove all the elements from that element.

Guest 2

So, if we had to remove all these quirks, we would basically, like, put whoever uses that normally at a at a small disadvantage just because we want to do we want to use the same run down. And and also, it was from a maintainability perspective because our thought was, like, if we have two separate runtime, whenever we are working on the first runtime, we know that we are in the client's runtime, and so we can use this DOM trick. And whenever we are in the custom runtime, we know that we are in the custom runtime, and we cannot use those DOM tricks.

Guest 2

And I actually got decently far with this. So, like, I built a a very small subset of the runtime.

Guest 2

And then because I wanted to try. Like, blame me, but, like, I built a very minimal runtime, like, where you could just use, like, props and state and, like, some basic element.

Guest 2

And then I build a very basic version of a custom render for links.

Guest 2

So right now, there is a links app, which is a to do app that I've built with Svelte, And I was so excited when I actually got warp.

Guest 2

It Wes, like, the my my favorite to do app ever. And the nice thing, like, to circle back to your question before, Wes, which is, like, how do you even relate, like, an input or a p tag to a native Android surface, for example? The answer to the question is really that when we will build this custom renderer API, Svelte will not care at all about that. Right? You write a p tag.

Guest 2

We just call the custom renderer and we say, hey. We want to render a p tag. And then it's up to whoever writes the custom renderer to say, okay.

Guest 2

A p tag is something that needs to display text. So what I want to create is a text,

Scott Tolinski

element inside links. So you could do that. So you could you could say, like, a custom render is like a translation layer then. Yeah. Basically. Yeah. But it's it's basically you links

Wes Bos

does links supply that? Like like, do they does links have tags that are like like a text tag? Or Just Okay. So you More or less in the sense that if you if you read the the links documentation,

Guest 2

basically, what they supply is the the PPI. Right? They called it the PPI, which I assume that that's how it's spelled. But, basically, JS an API that is close enough. Like, it's similar to the DOM API in the sense that you can have, like, underscore, underscore create element, and then you can create an element. Underscore, underscore set attribute, and then you can set an attribute.

Guest 2

Underscore, underscore, like, flush three, and it will rerender a specific portion of the page. There are specific, attributes. And I I guess, like, if you ever use React Native Mhmm. It will feel familiar with you because the links element are called view and are called text. So, like Yep. They are not called p. They are not called div or span. Like, they are literally called text and div. But the nice thing about writing a custom renderer is that you kinda get to decide which elements you want.

Guest 2

So, like because at the end of the day, Svelte will just invoke your function and say, hey. Please create me a p tag. And then if you want to make the translation between a tag and a text tag inside inside links, it's kinda up to you. And it's very nice because, like, you can literally create whatever element you want. So, like, another thing that I did for a talk and also for fun, I created a terminal renderer, a very crowd version of a terminal renderer, I would say, because one of the reason why ink is popular, but also because it's kinda slow, and we've seen this, like, going around because, cloud code is built with ink. One of the reason why it's kinda slow is because it's using yoga under the hood, which JS, like, a library built by Facebook, I think, that basically tries to mimic Flexbox.

Guest 2

Like, you can just give it a bunch of, like, data, bunch of objects, and it will calculate where those object will in inside, a thing. So, like, this is a process that is kinda slow. And so ink, it's much more featureful because they are doing this so you can actually move stuff around and do, like, flex Bos and stuff like that. My terminal renderer was much, much more stupid. I was just using some basic NC code to, like, order stuff and do stuff. But it was very fun because, like, I had a Svelte component that was literally named, like like, counter dot belt, and I had, like, text, which is counter with the color attribute, which was one of my color. And Mhmm. Pressing play, it was basically using an effect to increase the count and then using the derived to derive the color, and it was actually working. You you could see, like, what you wrote inside the terminal changing color reactively. So, like, it was very fun.

Wes Bos

Okay. And, what about CSS? So React Native and Lynx support a subset of CSS. Right? Like, that's what yoga is. It's it's translating regular CSS into whatever the, like, iOS or Android equivalent JS. But they one of the biggest pain points there is they don't support Grid, which links does support. Yeah. So what does that look like with with Svelte CSS?

Guest 2

Yeah. So, in terms of, like, Svelte obviously has scoped CSS.

Guest 2

And the nice thing about that, about links specifically, is that, as you said, links really like, while React Native is kind of a borked down version of CSS, like, they are they are doing it like, they support a bit of flex. They support some, CSS stuff, but they don't support everything to the point that if you want to use Tailwind, for example, with React Native, you can't use Tailwind. Like, you need to use a NativeWind, I think it's called, which is basically a new version of a Tailwind written specifically for React Native JS people usually dial with React. Right? Right. Except, like, for for the the team, like, links instead.

Guest 2

Like, they have a very good support for CSS. So you can just use CSS, and it will work, basically.

Guest 2

And so in my POC for links, like, that part is actually untouched. So, like, you write your CSS, and what's the compiler produce is just the same CSS.

Guest 2

And then it's up to you to actually, like, it's the it's more of a bumbler work. So, like, the work that I Node for the for the links POC was that I've used the links bumbler to say, okay. This is my CSS. The CSS type JS component.

Guest 2

Please make it work, and it worked.

Guest 2

The the moment you started doing that, it just automatically worked. So probably if you want to do this translation layer where a p tag is a text, you will also need to do a bit of work to change the CSS into the other forms. So, like, you will need to do a bit of work. But the at least for the moment, this is probably something that we can explore a bit. I don't know if there any work that we need to do to support custom renderers, like, in the style tag, basically.

Guest 2

There will be some Yarn of that can't be ported to custom render, like, that that will be disabled for custom renderers.

Guest 2

Because, obviously, like, for example, bind value really only works if we, Svelte, can register an input. Mhmm. And you put event listener on the input. So, like Yeah. There's a very specific amount of bind that you can do. So binding will probably be disabled, like, in in custom renderer words. Yeah. Obviously, you can still use a listener. So, like, there is, like, Node of the function that you need to provide when you create your your custom renderer is the React way.

Scott Tolinski

Wait. So what what does this realistically look like in terms of, like, actually existing for for people to use? Timeline, what what's the yeah. Where where are we at?

Guest 2

So, again, basically, right now, we had, like, we had a lot of discussions with the rest of the team.

Guest 2

One of the last discussion that we had, actually, we realized that our idea of splitting to two run times was more maintainable in the sense that when you write something in one run time, you have a very clear idea of where you Yarn, but it was very not maintainable in the other sense because, like, you have a lot of code duplication that changes slightly, like, just in, like, two or three characters is different. So, like, it would be a nightmare to maintain. So what I'm doing right now is actually rebuilding my POC so that we can use one single runtime, and then we use whenever we we have this trick, like, that we use the DOM API in a certain way, we actually branch out. So I would say, if there is a custom renderer, we can invoke the custom renderer. Otherwise, we can use the the the shortcut. So, like Yeah. Yeah. Wes make the code slightly more complex in, like, having one single runtime, but it should help in the maintainability long long term because we will have and if we fix one bug in another related part, we don't have to fix that bug also in the custom run time. Otherwise, we would have a lot of PRs that are basically just copy and paste of a fix in two separate files. So like that that would be annoying. So what I'm doing right now is basically trying to rebuild this this kind of part. In terms of, like, when will it be available, I don't know because, basically, like, after, like, we my mother founded me for, three months, we are now actually looking for sponsorship for for this. Like, if there's some companies out there that wants to, like, build a native app with Zelle or even something else. Like, for example, we had discussion for people that wanted to build, I don't know, with WebGL.

Guest 2

They wanted a renderer for WebGL, and so we are talking to sponsor that. And if you are interested in sponsoring, by the way, you can go to svelte-custom-renderers.com and, you you get in contact with us. What I hope is that if we find a bit more funding when I was working on this before, I like, AI was really not there at all. So I really hope that with the aid of some agent, I might be able to go a bit faster on this thing. And, unfortunately, this is a big enough problem. Like, I kinda feel sometimes I kinda feel, like, annoyed with myself because, like, I know that, like, technically, I could work on this in my free time like I do for rest of the resource. Spend all of your time. Yeah. Yeah. Like like the rest of the resource. But the problem is that, like, this is a big enough thing that I really can't work. Like, if I if I was to work on this on my free time, I would have zero free time, and I would will will Scott be able to contribute anything else to Svelte for a very long time.

Guest 2

And also working at increments of, like, one hour because I have a four year old kid. So I it's Node like I don't have, like, all the time of of the warp Yeah. Being assigned. You gotta justify,

Scott Tolinski

DD sponsorship to work on this. Honestly, this is a huge project.

Scott Tolinski

So we'll make sure we link that up. Syntax is going to be sponsoring some of this effort here because, we use we use Svelte, full time, and syntax.fm.

Scott Tolinski

We have a new SvelteKit app. I obviously use it for for everything. But, man, it would be really cool to have to customer under support. And to be clear here, folks, because we've been talking a lot about native apps and links and stuff like that, we often get, like, people saying, like, why not just use what is it? Or even, like, Cordova, whatever they call those things now, which is basically just a Wes view rendering web content in the DOM.

Scott Tolinski

That's not really what what this is. This is React Native. This is a real native app that is being translated from Svelte code into, whether that is Swift or, what is with Kotlin? Does Android uses Kotlin nowadays? I believe Wes. Yeah. Yeah. But but this would be done through the Lynx project, which is what TikTok is built on. And it's a really, really cool thing. So, if your company's out there, you might find, interest in this sponsoring this as well. We'll make sure we have those links available.

Scott Tolinski

Really, really exciting work, and, I'm really, really stoked to see what comes of it. And by the way, there is, like, a guy

Guest 2

I I just saw it, yesterday in in the Svelte Discord that actually took my POC for links and somehow because, like, it's a huge undertaking because it's using a very old version of Svelte custom made for that and stuff like that. And he actually made it work with Hermes, which is the engine behind React Native. So, like Yeah.

Guest 2

It's

Scott Tolinski

it's it's so wild. That is crazy. Alright. I gotta check that out. Alright. Well, thank you so much for sharing all this. Man, I I I'm excited for all the work and and really thankful for all the work that you and all the the Svelte maintainers do as a huge fan of this project. Now is gonna be the part of the show where we get into sick picks and shameless plugs.

Scott Tolinski

Sick pick could be anything that you're just enjoying right now, and a plug is anything you wanna plug. It could even be the Svelte customer nurse thing that, our website that we'll we'll link up to. Yep. I mean, fine. So, I mean, I would say, like, a sick pick is definitely, like, for me, something that I've been using a lot lately,

Guest 2

and I really enjoyed using is OpenCode. It is my main driver for Wes I use AI, and

Scott Tolinski

it's lovely. And I I really like it, and it's very flexible. Yeah. I do too. I I I use it as my main. And it's just like, I don't wanna be using the product that's tied to one model, and I I warp it to be fully configurable.

Scott Tolinski

When when I I got brought out to talk to the Versus Node folks about the, like, Copilot CLI, and all my requests were like, I need to be able to customize these paths. I need to be able to customize this. Like, it's all the stuff that I I have set up in in OpenCode. I I love to tweak my tools, so I get that. And shameless plugs, what would you like to plug? Well, obviously, like, I will plug once again, svelte-custom-renderers.com.

Guest 2

If you want to join the initiative, you also get a shout out from our socials, and you will now bring this to to the to the to the finish line.

Guest 2

If I'm allowed, I will also like to shield another project of Node, which is TMCP, which is it's something that I've been trying to shield as much as possible because I've built, basically, a competitor SDK to build, MCP server with TypeScript.

Guest 2

It is, like, in my opinion, a bit more, lightweight.

Guest 2

It has less bloat of dependencies.

Guest 2

To be fair, like, the official SDK, it is getting way, way better. But, yeah, it's I've built this, like, alternative SDK, which uses web Wes and web response instead of, Node Wes, node response. It's using standard library, so you Yarn not tied to Zod. Like, you can use whatever validation library you want. Oh, yeah.

Guest 2

It's much more modular. So, like, I have, like, the transport Yarn separated so that if you want to build your, HTTP transport, you don't have to get all the dependencies of the SDIOU transport.

Guest 2

And much importantly, like, vice Vercel. Like, if you are building an SDIOU MCP, you will not get expressed as a dependency and stuff like that. Again Yeah. This is like the old SDK is getting way, way better. And, but, yeah, the Svelte MCP is built with TMCP.

Guest 2

The storybook MCP is built with the TMCP. What about the syntax MCP?

Scott Tolinski

The syntax MCP is built with TMCP because I actually opened up VR to build the syntax MCP. I love I I'm sorry for not getting that merger. We're working on a big re rewrite, so there there's, like, two precedents there. Yeah. Wait. You you you said, you can use any type of, like, you said dot or what what's your preferred,

Guest 2

schema library for that?

Scott Tolinski

Which one? Volleybot.

Scott Tolinski

You like Volleybot the Wes. Why do you like Volleybot the best? In terms of validation libraries,

Guest 2

if I have a validation library, I don't want to feel bad if I ship that to the client. Like Yeah. Maybe I don't need it, But if I need to ship it to the client, it's nice to know that my users will get, like, one kilobyte instead of 10.

Scott Tolinski

Cool. I love that. Hell, yeah. Beautiful.

Scott Tolinski

Cool. You got anything, Les?

Wes Bos

I don't know. I I think this is good. I'm I've got a a list of things to check out. I've we talked to, Zach when he came on. He works at at ByteDance about Tolinski, and this was before it was released. And and now it's it's out, and it's really cool to see people writing custom renders and and fussing with that. So certainly excited to check that out now.

Scott Tolinski

Yeah. Yeah. Absolutely. Cool. Well, thank you so much for coming on the show. It's been a long time coming, and, I'm sure we'll chat soon.

Guest 2

Yeah. Thank you for having me.

Scott Tolinski

Peace. Bye.

Share