Episode 64 - Free
Nate: Development's so complicated and there's so many, if you're just someone who wants to be creative and build ideas and like build and design out your dreams, I don't think it's ever reached the point where it's just doable.
So I've been working on this thing called Tamagui for the last, couple years I guess, really. But it's kind of like a full stack, like component kit style system, um, and like optimizing compiler
Andrew: Hello , welcome to the Dev tools FM podcast. This is a podcast about developer tools and the people who make 'em. I'm Andrew, and this is my co-host Justin.
Justin: hey folks. Um, our guest today is Nate Weiner. Uh, Nate is the creator of tamagui, uh, which is a UI kit for building cross web React native apps. Nate, it's really awesome to have you on. Uh, before we dig into the episode though, would you like to tell our listeners a little bit more about yourself?
[00:00:57] Tamagui Origin
Nate: yeah, sure. Thanks for having me. Um, I guess, uh, yeah, I don't know. I've, I've just been like tinkering with, um, with like making apps and stuff since I was like, you know, in high school. Um, kind of like came on board with, um, I think I actually just hired some guy to do like a P H P website for me once.
'cause I could, I was doing like just design and like basic H T M L and I couldn't figure out how to do backend. And then just very slowly worked my way up into like rails eventually. I think that was like a big. Turning point for me where I was like, oh, I can actually build stuff. And I think like the theme of my entire, like development career has just been that I feel like it's development's so complicated and there's so many, like if, if you're just someone who wants to be creative and build ideas and like build and design out your dreams, it's never, like, I don't think it's ever reached the point where it's just doable.
Even if you're decent at programming, like even if you're a really good programmer today, like myself, like I, I, I still don't feel like I can quite like pick up something and just build, uh, that thing without maybe spending like months and months and like dealing with so many unnecessary complications.
So I think, uh, in some way or another I've been trying to help that come along and I think, you know, that dream of kind of rails, I think Rails was the closest I ever got to. Like, I can ship, you know, something that I can imagine within like a, a few months or something like that and actually have it be, be nice.
And so I've been working on this thing called Tamagui for the last, uh, Uh, yeah, last couple years I guess, really. But it's kind of like a full stack, like component kit style system, um, and like optimizing compiler that kind of, I think, you know, one of the big, I think, problems in building a cross platform app that runs on native and web is that you end up with either sacrificing a lot, like sacrificing the intuitiveness of how you style.
And then, or if you do get a really nice style library, um, then you end up sacrificing performance because that style library has so many abstractions. and so that's what Tamagui's trying to solve is like if I can have a nice style syntax, but also not have it be like terribly slow on the web and use actual, like web primitives, that would be the, the dream.
So trying to make it work. Um, and, and yeah, I guess that's kind of like a, a high level view.
[00:03:03] Ad
Justin: so we'd like to thank Raycast for sponsoring our podcast. Raycast is an app for Mac that's like spotlight with superpowers besides just quickly opening files, URLs, or apps. It provides clipboard history, window management, schedule overview, and more. It also has a clean React based a p i and an extension store to distribute your own custom extensions.
Andrew: Raycast has lots of cool things built in, but the community provides a lot of extensions that are even cooler. One of the most useful use cases for an extension is actually within your own team though. With a custom Raycast extension, you can codify your team's workflows and all the information your team needs to access about the projects you work on.
An example of this I recently saw on Twitter is a developer from the storybook project. Varun took all of storybook's design system and tokens and put it into a Raycast extension. With just a keystroke, you can access any of those values and copy them to your clipboard. You can even convert between color values and color representations.
Justin: Yeah. And To add to that, you should also try Raycast Pro. That's their premium feature, but with Pro, you can take advantage of Raycast ai. Which is extremely awesome 'cause it lets you do all kinds of typical AI tasks in line with whatever app you're using on your Mac. So you can summarize text or translate text, a lot of really cool functionality there.
You also have other interesting features like cloud sync. So if you have multiple Macs, you can sync your raycast configuration across different apps and it gives you things like custom themes. So it's really cool. You should definitely check it out.
Andrew: To learn more, you can visit raycast.com or you can go listen to episode 38, where we talked to Thomas, the c e o, about the product and how it's built.
[00:04:42] Styling all the Platforms
Justin: This is a pretty awesome endeavor. Um, so when I worked at Artsy, we had a React native app and a web app, and we tried to do sort of the same thing. So their design system palette is we wanted to share across platforms and eventually just split them. Uh, but interesting 'cause you, you're right, there's a lot of interesting challenges.
So like we had evaluated like react, uh, native Web back in the early days and that. There are just a lot of trade-offs and, you know, some of the old solutions are pretty clunky. Um, so am, I'm curious, uh, had you, had you tried this before, like on some product that you're working on before you started Tamagui ?. Um, and sort of what led you to the approaches that you've taken so far?
Nate: Um, yeah, so I, yeah, I mean, in a sense, I, I've worked on this a few times. Like I think Tamagui , you could consider it almost my third or fourth try at some sort of like UI system like this. Um, but there, uh, I was working on. Um, something that was similar to React Native before React native exists, but it was, it was more similar to Cordova maybe, but like really trying to replicate the iOS look and feel like almost perfectly just using like React.
Um, which was very complicated. So that was kind of a first attempt. And then I, I met up with a co-founder, uh, through that, and we raised money, um, through like really good investors. I moved to the Bay. I had never been, I never lived, you know, in San Francisco or anything, but I moved to the Bay to do that startup.
It was a dev tools focused startup. Um, and it was, uh, also had like, uh, I mean it was a little bit more ambitious. It was maybe like we, we modified, um, we actually modified JavaScript. We took Babel and forked it and added like a Vue keyword and then inside of there you had have these reactive variables and there was a whole compiler set up.
It was a little bit like Vue, or sorry, like Svelte. I think it, it was like three years before Svelte existed, there's a cool demo video on YouTube. I can, I can link it. It was called Motion and we actually built it out. It was. Really interesting, like the H M R was as you typed, like it was so fast, you could just keep, you could like tweak values in real time.
It had a compiler that pulled out Css from like dynamic values even. Um, so it had like kind of that similar idea behind it. Um, and it just didn't end up going anywhere for various reasons. Uh, but what's one cool, like, side note from that is that, um, when we first were showing that demo video off to people, we started getting like kind of a bunch of people in our, our Slack at the time.
And like a bunch of people were getting interested and, uh, I remember like Evan Yu of vue joined our Slack and he was like, this is, so this was like, I think before vue even was called vue or something. It was like ver maybe it was version one or, or pre version one. And he's like, can I take some of these ideas?
And we were like, yeah, go for it. So it was kind of cool, like I think, you know, we didn't end up launching the project, but there was some influences I think down the road, uh, that it had on, on the, on the ecosystem. So, but yeah, long, long story short is that I definitely, um, Have tried this a few times. Uh, I was booting up a new project at the end of the pandemic, um, and it needed to have native support.
So I was kind of like, well, you know, I had this UI kit that, the last version of it that I had tried, which was just for an app before that, that I was working on. It had gotten too bloated and it had gotten kind of like I had thrown in a, it's really hard to design these things. 'cause down the road you try and like do something and then you end up like realizing that the whole fundamental design, like, you know, the css, the whole Css problem of like merging styles down, uh, cascading styles.
it was like I was trying to get it to like be very correct and I just literally couldn't fix some of these features. And so I had to rewrite it using atomic styles. And then I realized that some of the way I had done some of the features in that last UI kit, the styling system, the, the, it wouldn't really work with atomic styles or at least I ended up in this giant mess of a refactor where I was like, you know what?
At this point I'm just, uh, I'm just gonna bail on that one. So, um, So, yeah, so then Tamagui was kind of like, okay, let me start over again. Of course. Uh, and I, I, I grabbed J S X style, which was this, uh, library that had already existed, that had a compiler. 'cause I, I kind of knew that like if I'm in a bridge native and web, um, it's like, it already was like my UI kit were already slow, just doing web only, uh, without a compiler.
So it's like even more so needed it. Um, and so that was kind of the genesis of the library.
Andrew: so, uh, like for our listeners who don't actually know, like how does it like work in the end? Like, uh, what is rendering to native and like, how do you translate that to, to web also
Nate: Um, yeah, so it's, it's basically it was originally running on React Native Web, so, um, same API Surface as React Native and React Native Web. Um, so you basically have a limited set of style properties that are very sim They're basically identical to web style properties, but like, they're just limited, you know, you don't have stuff like background backdrop filter and these type of like, more fancy props.
Um, but you have like all the basics. Um, and yeah, originally I just built off of React Native Web, um, and even rendered to that. But, um, there was a multiple things that were sort of like making that very difficult over time. One was that just, uh, react native web refused to support class name and, you know, we're compiling to atomic c s s.
And so it's like, how do I pass if I can't pass in a class name? I literally was patching, like I had a, script that would go into your node modules and patch react native web to make it work with, uh, class name for, for the first like, Six or, or year or something of like Tamagui ago existing before when it was actually called something else.
And it was very small, but eventually I was like, this is, you know, I, it's just like I can't really rely on, um, you know, they, they closed the issue saying like, we're not gonna support it, which was, in my mind a kind of a mistake. And, you know, there's, at the end of the day, if you don't control the whole fundamental styling system of your library, then it's kind of, so, so I ended up slowly like, moving it off.
It was a huge amount of effort. Um, but now it's basically its own style library. Um, it's native runs on native and web, like on native. It, outputs to, um, you know, like a style sheet dot creator just objects basically. And it passes those objects in as, as a style property And then on web, um, the one, one big thing behind Tamagui is that it's, um, it's not like zero runtime on purpose.
Um, just because setting up a compiler and a compile step is always such a big, um, commitment and a risk almost too. 'cause like, you have to trust that like this compiled time process is working. Um, and I wanted it to be easier to like run without it. So like, it, it runs completely at runtime as well as at compile time.
So you can just plug it in without any compiler setup and use it, and it'll output class names, but you know, it generates the c s s and inserts them, uh, on the fly or at startup. It kind of, depending on if you use like a styled component versus an inline style. Um, but then if you do plug in the compiler, it will, um, analyze, you know, everything and it'll pull out c s s at build time and do a bunch of other nice things too, kind of optimize and, uh, a few other things that we can get into.
Andrew: so I'm assuming React Native Web didn't wanna support class name because like there is no like native version of that on, uh, react Native. So like, did you have to solve it the opposite way too? Now that you have class names, do you have to make those work on the native components and like, is that like a subset of CSS basically?
Nate: It is a good question. Um, but the answer is just really like the, the class name just is a no op, basically on, on native, I mean, class, class name is basically an escape hatch for web, which I actually use it all the time. It's nice. You can just go write some css like you can do, like, you can add your own little, like add-ons, like tailwind style, almost like I just add a bunch of little things that aren't supported on through the React native, like official A p I and I use class name as my like, um, way to target web.
now there is like a platform selector where you can do platform web and platform native and platform iOS and do like specific styles to each one. Um, but still you don't get like, you know, that's still limited to the style properties that it supports. So, um, so yeah, it's, it's a no op on web.
expo's working on some interesting stuff right now. They seem to have gotten like a CSS working for Native and they're working on, and, and I think they've built that in order to get like some tailwind type stuff working. Um, For native, so you can do like tailwind class names and, um, it's a, it's also a limited subset of c s s and, uh, from what I understand, it also doesn't cascade, so there's no c um, just cs.
Uh, but yeah, so there's some differences there. But it seems like we may get some sort of like, form of Css.the whole point of Tamagui agoo is kind of not to do css, uh, like I'm
Andrew: Mm-hmm.
Nate: inline styles maxi, like, even like tailwind, right? It kind of admits like you're sort of avoiding, like, I like the, the component like react component model combined with like local styles is I think is a really beautiful setup.
So it's kind of funny to see that, that happening, but it, but it makes sense.
Andrew: Yeah, I have a lot of opinions in this space. I've done lots of design system stuff and I do like tailwind and I also like scoped c s s modules. I think they really mix well together. Like when you're designing components, you don't wanna design some things in like sometimes width or spacing or all these other things.
And I think utility class names are like such a nice bullet for that. But, uh, you could easily argue that if they were just like style properties, like you have, it would work just the same. But like combining those two things, I think creates like the most ergonomic design system for sure.
Nate: yeah, I mean, I think the in, I mean, I, I actually, people say like, you know, can we get like some tailwind support in Tamagui and that's possible. Like I, I definitely have been thinking about adding like a library that's kind of like maps tailwind, so you can just use like the exact same props. It probably would be good for that adoption and stuff.
But the, uh, the inline. Props especially. 'cause there's a short, there's a concept of shorthands in Tamagui . I mean, you can basically get the exact same experience where it's mx equals like whatever, um, you know, p or all the different, like shorthands you, I, the default ones that we have are basically the same.
Um, kind of like same, same idea. And what I like is that you get types too. So you get like, it's, it's, you know, TypeScript, uh, auto completes with your just editor without any sort of special plugin. Um, there's so many benefits. I mean, like, uh, you can like, you know, destructure them, um, as props and then, and then play with them and change them and then put them back onto props and, and like, you also get like nice merging, I think with Tamagui, which is, I have to plug a little bit.
But yeah, you get nice merging, which is like, the order of the props is important. So, uh, that was like a big realization at some point because, for example, we have variants. I don't know, I don't wanna like get too in the weeds maybe if people aren't familiar, but like, if anyone who's worked with stitches, it's just a way to like expand.
I'm sure maybe Tailwind has something like this too, where you can like shorthand for like an expanded amount of, um, styles. Maybe they don't, I dunno. But um, but basically like you can have a shorthand that's like, you know, uh, huge or something like, and if it's such a true then it expands to be like, you know, set the radius, set the, a bunch of other properties, maybe the scale.
Um, but the problem is then like, you wanna be able to control that and like, um, like override say like if I wanna override, like expand that, but then override one thing, um, I realized at one point that like if as long as you make those the prop order significant to the styling system, so you can have huge, and then the next line you could have like maybe set the border top right radius to zero if you just wanna have like a sharp edge or something like that.
Andrew: And, uh, so that was kind of like a big thing that, and it, it lets you do this really nice thing where you can kind of like have an a p i surface where your component lets external users override some styles, but then like maybe you control the rest of the styles and stuff like that. It's nice that it's, uh, enforced by TypeScript. There's a utility called Tailwind Merge, which is like, it kind of does the same thing, like order inside of the, the arguments matters and it'll override previous classes, but it's a lot nicer if it's just like built into the programming language and you don't have to like, think
about it at all.
Nate: I'm just curious with merge, like how, uh, ' cause like you'd have to like string split, like if you wanted to do something like manipulation in, in the middle. Right. It's kind of weird.
Andrew: Not
ergonomic at all.
Justin: No, it, it's kind of rough. Um, artsy was using, uh, style components and styled systems, you know, and there were some obvious like performance trade-offs there, but, I do think that this purchase is really interesting 'cause the, the types in particular helped a lot. Uh, it does make it very explicit and, and kind of terse, which is nice.
And also you get documentation for it too, so just like cover over and see what it is.
Nate: A funny thing that we're running into now is that, uh, TypeScript can't handle it at a certain level because you can nest these style components. There's so many properties if you think about it. 'cause it's, it's like hundreds of style properties and then you have pseudo styles like hover press, and then you have media query styles.
Like, um, so, so that's multiplying. Uh, and then also you can have a media career with a pseudo style. Like, so, like if it's a big screen plus hover, right? So then that's another multiplication of all those like types. And then you can nest them. So you can like styled, styled, styled, you know, keep nesting those.
And each time it's adding more. So at some point, like it's actually like we're at the very like tipping point where I've tried to add features and I run into things where like if you nest five times, you get the like cannot recur. Like what is it the, in like it may be
infinite depth.
Excessively deep, yeah.
It's an bane of my existence that, that air.
Andrew: That's when you know you've won programming though. As you, uh, you run into that compiler error.
yeah and are
not
Nate: actually infinite.
[00:17:16] Provided Components
Andrew: Yeah, it's not, no. near Infinite. Uh, so one of the cool things that Tamagui also provides, it has that base layer of styling, but it also provides a lot of components.
And the components remind me a lot of Radix, uh, but I'm really interested to know how they actually work. Like, are you using radix underneath or do you have to like implement it in such a way that you can do it on
Nate: um, yeah, I was definitely inspired by, by, is it Radox? I've been calling it Radix
Andrew: I, I'm bad at this.
Nate: Radox Radix Uh, yeah. Uh, okay. Um, I'll do, I'll go with Radix though, but I've never actually heard someone say it out loud, so I have no idea. Um, but yeah, I mean, it's, it is rad. So that would make sense. Um, no, they're amazing. I mean, they did such a great job. With that library. I was very inspired. I love the composable components.
A p i I think it's genius. I think that's like, I mean especially like, it's just, it's kind of like the, one of the hardest problems in styling or like in front end is just like, how do you provide an api surface, but also let people like customize every part of it. And you know, in the past people you've had something maybe like where you have like a prop that's like text props or inner, you know, frame props or something like that.
And you, you just take all these sub objects, but that's just, it doesn't nearly give you what you need because it's just like how you want to resort, maybe like the inner contents, right? You want to just, you wanna flip the ordering or, or you wanna like nest them multiple times. It just like, it, it immediately runs into like impossible problems.
So I think Radix was great. Um, the obviously yeah, for Native, um, I couldn't just use them or, or I would've, and there was an option maybe to like write it twice, but I obvious, you know, the point of time we was to try and see if you could bridge that nicely and React native does and react Native web do give you those nice APIs.
Um, Or the, that, that a p i surface gives you a lot of the stuff you need to implement it. So my process was actually, um, to most of the time just to steal, like, to take the source, obviously leave the licenses in place, but, and then to like rewrite it. Um, but use kind of a similar structure. So like a lot of the Tamagui components started as like, you know, we need this, let's think of the, the right way to do it.
Maybe for native it, some of them are a little different in like how they actually work or, or what they do, but a lot of them are very similar and, and even started out as just like taking the radix source, kind of stripping it down, re-implementing a lot of the insides, um, and then getting it to work with some of the more Tamagui like style ideas.
Um, and uh, yeah, it's, it's been really nice. So like, yeah. Yeah, so it definitely, even the website, I think we took some of the ideas from, like, I think I even took some of the website, like documentation, like the, the show code and some of the toggles and stuff like that. I was just, I. You know, great artist steel.
Um, but yeah, shout out to the, the, that team and think they did a really good job. And there's some differences, like, uh, Tamagui didn't start out as un styled, um, but it does have an uns styled prop now for almost all components. So you can basically take the styles out. Um, I think for version two, we're sort of thinking about going fully, like having like an option just to import it as un styled basically.
Um, or yeah, just to bring your own styles a little bit more cleanly. Uh, but we're, we're almost there. Basically have it almost working. Um, and then there's some like, cool stuff that's come from that radix style approach, which is like one of the big things that I think is one of the coolest parts. And I, I just haven't done a good job of like, talking about it or demoing it.
I've got like some cool demo videos for sure that I think we could, um, put out that would show this. But, uh, we have this idea of an adapt component that it, it, if you nest it inside of your, like certain components, you can adapt them to other components at certain for certain platforms or certain media queries.
So for example, like a modal. Or a popover, you can adapt into a sheet, uh, if it's on like a touch device or something like that. And then it'll actually portal the contents. So it's kind of cool. Like you, you just have this like one big thing that's like, um, you know, your portal and all has all the contents and everything.
You need it. And then inside of that you just put adapt, and then you put sheet, and then you have your sheet, all your sheet com components, which are also radix like, so you can customize all the sheet stuff. And then you just, inside of the sheet where you want to portal it, you put like a dap dot contents and uh, it's pretty cool.
It'll, it like magically turns from a, from a popover into a sheet, uh, on a small screen or something like that. And, uh, the amount of like stuff that that's doing, you know, compared to like if you were trying to implement that yourself is, is insane. But also, I just think the Radix like that flexibility, like where you can, you can fully customize both of the sheet and the popover and then adapt them into each other because they're nested composable components like that.
It's like, I think it's, that's, it's a really cool, like maybe one step, it's like unlocked by the Radix A P I. Um, but also kind of working in a, in a new way. That's pretty cool.
Andrew: yeah I remember reading like five years ago, uh, like that composability and React was like, what you should shoot for, and it like boggled me. But then, uh, once I started building design systems and found like the, uh, the sub-component pattern, it, it changed it all. I was like, oh my God, it all makes sense. Like I can just add tool tips to things. Uh, I was gonna ask you about how the styling works because. Styling on the different platforms is far different. And if I'm creating this like shared system, do I like, am I giving up some of the platform specific styling or do I still
Nate: Yeah. So well, I mean, part of that, yeah, I mean, you definitely are constrained to the style properties, but you have obviously, like we kind of touched on with class name and stuff, you do have escape patches. You also have platform specific style selectors now, which is a new feature, just a. Maybe like a month ago that we landed.
Um, so you do that, that actually is pretty nice. Um, and then I think there's also in just React, um, native in, in general, they have this idea of like, actually just fully forking things by using a file extension. So dot, android web dot iOS, dot native. So we use that like even internally in Tamagui for example, the popover is um, actually just well, it uses floating ui, which is shout out to floating ui, amazing library, um, by the guy who made, I think it was called, what was it called before that?
Like
Pa
Justin: Popper, I think Popper
Nate: Yeah, I think his name is James. I don't know if I remember his full name right now, but, uh, but yeah, I mean, he's done this before and it's such a good like, library, but it, it works on native and web, but they're like, you know, there's different levels of support. So for example, for that component we have like a dot native version and they share a lot of things, but they also diverge in, in a few significant ways.
And, and I think that's like a nice, like. A kind of escape hatch. So yeah, the, the escape hatches in tamagui are pretty good. You have on the, if you just need like different styling, you have the style selectors. If you need like web specific styles that aren't supported, you have class name. Um, and I guess you could use it inline style prop.
'cause the style property technically will accept like any style, valid style as well. Um, and then, yeah, and then you have the file extensions for complete divergence.
[00:23:45] Accessible UI
Justin: Yeah, an interesting thing that we'd always had a challenge with was, um, So some of the, the, there are some nuances with like the flex layout and react native that can be sort of weird and require like different markup. Um, that was always one challenge. And the other thing was, um, it was sometimes hard to build, uh, accessible web ui.
Like you had to, you had to be very careful in doing that 'cause it was really easy to leave it out. And especially it depends on who was building the component and what experience they had. So it was like a few different things of like ending up with sort of weird markup depending on the platform you're targeting.
And sometimes that created a split, um, you platform specific features like accessibility, things dropping out. Um, do you. Have any recommendations for people. So let's say they're, they're picking up Tamagui and they're like building out a product with Like about how to sort of approach some of these like platform differences or how to think about developing across all these
Nate: Yeah, that's, that's great. Uh, a great kind of like, interesting point. There's like a lot to it, I think. Um, I would say, well, one thing is that definitely react native, uh, web and in general, react native are getting better about a lot of this stuff. Like, you touched on the flex differences. I think the new, the newer versions of yoga, they've, they have like a much more, there's like,
You can, you can opt into the newer like mode that's much more consistent. That's pretty cool. Um, on the like accessibility prop side, uh, react Native and React Native Web are both moving towards supporting much more like standard web properties. So the Aria properties are now supported. Um, uh, data attributes are now supported kind of in a standard way.
They're, they're definitely like, you know, they had a bunch of like they had like these weird properties like data set or like accessibility props that were different and, uh, now they're deprecating most of those and moving to like web, web looking ones, which is, it's very nice. We use Aria properties internally.
Um, I think there's a suite of hooks called like React Aria, I believe that's Cross pla that does work on native as well. Um, so probably if you're like also concerned about really getting a high quality there, you could check those out. Um, Tamagui. Tried to, I tried to keep all the Radix accessibility stuff in place as I adapted it to native.
So it, I, I'll admit that it's not the best tested, you know, like, um, but we do have really good, pretty good keyboard controls and all this sort of stuff. Like, uh, um, you know, there are abstracted, like one nice thing about React native is that it abstracts those APIs, like keyboard APIs are kind of standardized across platforms and stuff like that.
So, um, but yeah, I mean, um, I, my recommendation is actually usually just to, to just build it for one platform. I mean, like, it's pretty rare that your first version of your app needs to be cross cross-platform. Um, the nice thing about Tamagui is that you have that optionality. And I really think that, like, uh, one, one thing that I have to get around with tamagui is like, people maybe see it as like, oh, well that's only good if you're just doing both.
If you're, if you're just doing native and web, then use Tamagui. Otherwise, you know, probably use something else. But I, I really do think that it competes with anything, like any pure web. Library. I mean, you know, some people may like not like this idea of using class name for some stuff, but I mean, the, the other features in Tamagui are just really, there's like some really, really well hard fought kind of like abstractions and features that are in some of these components.
Um, and like the style system in general I think is kind of on par with most style systems in terms of like, you know, the type coverage, the feature set. Uh, it's really complete. Um, it's quite fast. And I think when you add in the optimizing compiler, which is pretty unique, you actually can get faster runtime performance than almost any other, like, even just like the really pure web focused, like even the zero runtime web focused sort of stuff.
Uh, yeah, maybe like the pure zero runtime, like web focused ones that, that, uh, don't, that where you don't abstract a lot of things and you're just using them straight, straight up. But I think what's nice about Tamagui style system thing is that it, you're allowed, you can build up this vocabulary and build up these variants and these like.
Um, abstractions that are, that are very like nice and elegant to use, but you're not actually paying the cost of like an extra layer of rendering depth of like a react component that's sitting in between you and your div. Uh, 'cause the optimizing compiler just reads that all, flattens it out into a div again.
Um, and so what I found is like, yeah, on the, on the website, um, on the homepage there's like one of the little sections, um, 'cause there's, you know, all these different sections on the homepage that show each of the different like, kind of features. And like in just the responsive feature section, it's like over 600 flattened, um, components.
So you're literally not rendering 600, um, react components on, on mount. And it, it makes our lighthouse score, I think like, uh, it's 15% or more, uh, improvement just by like flipping a switch. But it's also like the lighthouse score is maybe even not in the, the best improvement. 'cause Lighthouse is actually maybe more sensitive to like the amount of java script you run.
And that's where like zero runtime really like helps. Whereas Tamagui core is about 20 kilobytes of JavaScript. And we also add, Nick, the website has every possible combination of features shown on the homepage because we're trying to show off all the, you know, all the stuff and all the components. Um, but the runtime performance is where it really shines.
'cause like, you know, it, it, you don't pay that cost on the next renders. And like if you have a lot of elements, you know, being rendered out, um, you can feel it and it's pretty cool to turn it on and off and like, oh wow, this whole area just feels like much faster. Um, so yeah, I don't know where I started on that answer, but, uh, just, just plugging it in I guess.
Yeah. Like yeah, like there's these differences in native and web and like I think tamagui does give you some escape patches, but, um, yeah, I definitely, I definitely wanna counter this. Like, I, I, I would love to see, I need to make it easier maybe ' cause the, the setup process can be, you know, you have to, like I said, we use those platform extensions for example, like dot web, um, and we also have like a environment variable that you have to set to like tell it.
Which environment you're in, and I would like to get rid of those too. Like that would be cool. Next steps is to have like at least a form of it where like it's just plug and play. There's no build step, there's no like, environment variable. Um, I think that would probably be the next step to really get like, especially web users who just, you know, you don't wanna fuss around with, uh, configuration if you're just trying to throw together like a landing page or something.
[00:29:48] Optimizing Compiler
Andrew: So I, I want to dig more into the optimizing compiler. Like how, how is it? Determining what not to render, because like in my experience, most of the React components I write, like I feel are necessary to, to render the page. So how do, how does the compiler choose what and what not to add or remove??
Nate: Yeah. So it is limited to Tamagui components, right? So it's not optimizing anything outside of the Tamagui world. Um, it, um, which is, you know, I think it's fine if. That's, that's a good limitation. I would be a very different project if we were just trying to optimize like any type of styling. Um, but yeah, I mean it, and it does de opt in a certain like various cases.
So like dynamic styling. If you spread, for example, props, you know, if you're spreading props onto one of your atomic Tamagui views, then obviously we have no idea what those props are. Um, so if it was a div then things would just fail. So we, we de opt on stuff like that. Um, on native it doesn't optimize as much because, you know, like on the web we can assume that there's c s s variables.
So, uh, there's a lot of fancy stuff around. I mean, there's a lot of like hard thought work because you can plug out, for example, animation drivers, um, and some animation drivers, like the React native animation driver doesn't support c s s variables. So we actually have like all this crazy like, amount of work that's like the optimizing compiler needs to know that if there's an animation on this, uh, component, um, that it can't flatten it.
All the way. Right. But, but if it's a c s s driver, it still can flatten it because it's c s s, so it can assume that. And then at the same time there's like these like very intense, like complications between like theming and like, if it's using like a raw value for this animation driver, it needs to track that and, and know that it, so like basically there's a lot of complications there, but, but it's on the web it optimizes a lot more because, um, c s s variables and, and media queries can be extracted and, and stuff like that.
So you can basically, like, assume a lot. Um, and then it just does like some analysis, so it just loops over all the properties. It try, it even does try to do, like using the node VM module, it tries to actually partially evaluate things. So like you can do turn areas, uh, nested turn areas like object spreads, as long as it can analyze them.
You can, you can even have like abstracted things where you pull out, you know, some props into a different file or into a, uh, up above, you know, in the, in the outside of the render loop or something. You can have like an object. Um, that even references other objects like it, it's trying to do some actual, like real analysis, um, using a combination of like babel and the node VM package, um, to like, to grab all the, like the, everything that's in scope and then like pass it to the node VM and try and run it.
And then if it comes back successful, it says, cool, we've analyzed everything. We can understand all the properties, uh, statically basically, and we can flatten this into a div at this point. But it can leave stuff like, you know, if there's conditional logic, it still leaves that, but it's just instead of like, instead of like, you know, passing to Tamagui, it's doing like a class name.
So it's like, you know, this class name equals this plus conditional that class name, concat it together, et cetera, et cetera.
[00:32:41] Cross Platform Animatio
Justin: That's awesome. Uh, another feature that you show off on the homepage and I've had various challenges with is just, uh, helping smooth out animation. Um, can you, can you talk. About like how y'all approach animation and, and maybe even for people who aren't aware, like what some platform specific issues you might have when you're trying to build something like this.
Nate: Yeah, the animations has been a whole journey. Uh, uh, it's one of those things, like I said, like I, like I alluded to that last UI kit. Um, one of the reasons I think it failed was that like, you know, I built it one way and then later on I needed to add features. And then you realize that those features just don't fit right.
And I was worried about that with, Tamagui. Like, I, I had, I was thinking about launching it, I had it mostly working for what I wanted, you know, the design system, the style library and everything. Um, and at the time I didn't have any like animations at all. And I had a choice, like, do I do no animations? Uh, in the first version, do I do maybe one type of animation?
Uh, like just the, the obvious choice would just be the React native, animated driver because that, you know, it's built into React native and it works. On web and native. Um, but then of course there's this dri there's this animation library for React native that's very popular called Reanimated. Um, it's very clean and much nicer.
A p i It's definitely more popular with like, maybe like people who are just into that, you know, react native world. They, they love to use that 'cause it's very fast and very cool. Um, and, and much cleaner APIs, right? So there was always that looming. And then there's also obviously c s s on the web, which the built in platform stuff, which could also save a lot of bundle size potentially, because the, uh, react native animated JavaScript is like 30 kilobytes, like minified and gzipped or whatever.
Like, it's a lot, um, to add in for just a website. And so I was at this crossroads, like, do I, uh, do I just ignore it or not? And, uh, and it just kind of worried me. 'cause like I, you know, I could tell thinking about it with like the compiler, it's like, well, what, how do you even, you know, do that? And so I decided to bite that bullet and I decided to go all the way.
It's just like classic kind of, uh, you know, developer. Syndrome of just like, well, you know, I've gotta try, you know, I've gotta do it. Uh, so I did end up implementing them. They, they didn't work well for like, a lot of the life of, to like, you know, I think, um, there was always like some bug in one or some or the other.
And, and, uh, it's been a, it's been a long journey, I think to get them mostly working. And actually as of like just the last few months, I think they've really come into their own. Actually, what's cool is the website was running on the React native animated driver, because that was kind of the best supported one.
And we've been, I've been working with, um, with a little bit with Fernando, uh, ROHO, who's, who built a bunch of cool libraries or in the React world, and he wrote this thing called Moti, which is kind of like a, it, it, it kind of abstracted reanimated for native and web into a nicer a p i. And he also, he, he exported this hook called Use Moti, basically that, um, that, uh, kind of like does all the low level stuff for me.
So we rebuilt the Reanimated driver using that. And got it to be a hundred percent passing on all the different, like things that we needed. Um, and I swapped it out in the website, which is pretty cool. Like we literally swapped the entire animation system on the website. And I don't think you can really tell, like, it, it basically, like you, you wouldn't know, I guess, unless you knew that we changed that out, um, which was really awesome.
Um, but yeah, I mean the problems have been, uh, there's a lot, there's a lot to it. I mean, the, there's a lot of likecareful logic in the style system. Um, for example, like, like I said, like we need to track if they're accessing values in the theme, um, that are raw values versus c s s. And so for, so our, our used theme hook and that powers the internal, you know, way that we access themes.
Um, and the way that people who use tamagui can access themes. You know, you can use, use theme hook or, um, it, it does like, uh, tracking of what properties you access, but not just the properties. But whether or not you called. To turn them into a c s s variable or into a raw value at the end. And if you do track them as a, into a raw value, it basically keeps track of, it's a little bit like, almost like a state system, um, that you would see like an observable type state system where each component is tracking whether or not you're accessing any of these dynamic values.
And then if so, it, it has to listen to the theme changes, um, and re-render when it gets a new theme change. Whereas if it's a c s s driver, it sees that you're just turning it into a c ss s variable, it doesn't track the theme changes. And so you save, like, 'cause the website's like this pathological case where you have a huge page of components, like way more than you would maybe in like a typical mobile app, um, on one page.
And so it, it's very sensitive, like if I ever de opt that, um, when you switch from light to dark mode, for example, which is like, you know, re-render the whole page in the, in a typical react native type setup, um, I mean, that's like really the flex I think of Tamagui is like the fact that that homepage of the website, you can switch between light and dark mode and it doesn't really use much work.
Um, because the only thing it's rendering is some of the, uh, animated components, um, and changing out their, um, their like theme values. Um, but other than that, it, uh, it basically doesn't have to re-render anything 'cause it's tracking, you know, so that like, the intersection of theming, theme changing animations, um, and the compiler are like, where things have got, like, that's where we've spent, you know, a pretty crazy amount of time trying to get them all working.
But, um, yeah, I mean, we could go on and on. I mean, there's so much detail to animations, but I definitely want to like, I I think now we're at a cool part too, 'cause we could keep expanding. Like there's uh, there's this, there's this animate presence library that we took from Framer motion, um, and just kind of adapted that.
And it's so cool. Like it lets you do these really nice animations, very declaratively. And I think there's like many like. Further upgrades, like timing, anim, like the multi-step, I guess multi-stage animations that we don't support, but we could get that working across the different drivers. That would be pretty cool.
Um, and, uh, yeah, just like, kind of like there, it's cool now that it finally works, uh, basically fully. 'cause I think now we are well set up to kind of like, keep going and, and maybe get more like, 'cause you know, c s s is very powerful with animations and we haven't really gotten to that level. Uh, we just have the most basic stuff, so, yeah.
[00:38:35] React Server Components
Andrew: it seems like a lot of the features that you're working on work towards making shipping to all targets just like trivial. Like I would never wanna think about all this stuff if I were. Setting up both of these, I would probably punt the issue far, far before getting to all the animation so on the homepage, you mentioned server components. Those have been a hot topic lately. Uh, how,
does Tamagui use server components? I'm, I'm interested
Nate: Um, you know what's funny, actually, I may need, we, we do support it like as client, as client, um, components. So we, we do work with it and like we've adapted to like, you know, incrementally output styles, for example, in the way that they expect it and all this stuff. Um, but originally I had tried to get full server support because that seemed obvious to me that like, you know, you want your UI components to be run, be able to be run only on the server.
Um, I don't know. It's a whole thing. I, I'm not a big fan of React server components. I, I really am not actually, I'm sort of maybe like one of the biggest opponents of it, um, for like a lot of reasons. But one of the, like a lot of reasons, I mean, the way it's being done is, is a lot of it, but also just the actual technical side of things and like, to me, I get the, the desire and I, but I wish they would've come up with a much simpler implementation because I, I think what's really making it complicated is that, um, is that you have this like dynamic back and forth where like you can keep going back to the server and re rendering and you can keep, and you can, you can interleave all the props, so like, in such a complex fashion.
Um, whereas I think if they had done something more, like, you can have this be a server component where it doesn't hydrate, but then maybe you're not allowed to like, you know, do certain things like you can't pass, you know, certain things down or, or you can't go back and forth multiple times. Or maybe you can just like only, um, you know, you can't have a client that then has a server or something.
Like, there's like some limitations to how the tree is structured. I think if there was some extra limitations where it didn't try to be so fancy, but, but my other critique is this, is that like, I wanna not hydrate a lot of my. My bundle, but there's no reason to tie that to couple that to react server components like, you know, islands or something is like a concept that a lot of, uh, a lot of other frameworks have started playing with, but there's no reason that like React couldn't support, like tell it that this component just can run on the server and never hydrate and just leave it.
Um, and like that would be, that doesn't have to be like coupled to this entire huge change. And I think so many apps that exist today as SSR apps would love to just be able to say like, here's some markdown content, you know, that I'm rendering and react, but like, just don't hydrate this. Like, I don't need anything inside of there.
It's just markdown. Like I don't need to interleave like some sort of like tool tip or something in there. Or if I do, I can do it in a, in a different way. Um, so I have a lot of different beefs with it. Um, I mean, I think it's fine. Like I think it works well for, for web apps, you know, I think if you're building like landing pages and stuff, it actually is a decent model.
But that's my other, my other problem with it is like in the native world, it doesn't. Really makes sense to me because Native is all about local first, offline first, optimistic mutations. Let me just query my data like inline very easily anywhere in the tree and I wanna mutate it. And when I mutate it, it should be instantly reflected.
And also like, you know, sortable and, and all this stuff, right? Like I wanna just like, you know, parse or firebase or, um, any sort of like of these data models where it's like, you know, how the linear, how linear sort of works, right? Where it's like, it's an, it's an app. Like it's what we know as like a desktop app for like an app.
You know, we used to like differentiate between server or like websites and apps in the big differentiator I think was that, was that like desktop or like mobile apps were very much like instant. They could do, they could store a lot more data locally so they could get away with like, making things feel a lot better.
And server components to me represent like almost a regression. Like you have to go to the server to do a route. Um, which means that like, I have an app that's, that we built using, uh, like GraphQL, basically like a very nice library on top of GraphQL. Um, and what's cool is that like the, like it loads, you know, the, the frames of all the next stuff.
It knows the stack view that you're in and stuff. And, and when you click to go from like the homepage to a search page or to go from search page to a results page, um, it basically animates that in instantly. Obviously, uh, it can do a transition to the next state. It can do like all this like cool stuff. Um, sorry, by the way, I'm, I'm taking this opportunity to rant about server components 'cause it's what I like to do, but, um,
Andrew: Go for it. thats what we're here for.
Nate: whereas like in the server components world, it, it literally, it's like the minimum cost you're paying is like whatever it takes to go to the server, get that thing and come back with the next state.
And like that's just, and, and, and people say like, oh, but you can, you know, you could still do optimistic or local first, but like, not really. I mean now you have two different totally different programming models, you know what I mean? Like, why would you choose that if you don't have to? Um, Anyways. Um, there's a lot to that, but like, so Tamagui, so, and, and so I actually tried to get server components working.
Uh, I had it, so working in the original V implementation where they used to, like when Shopify was working on re when they were working hydrogen and they had like a full on React server components model, um, I got it fully working to where server components actually rendered with, with Tamagui. Um, and then when next came out, I just couldn't get it working.
There were so many bugs and stuff. That was the other thing is like, it's just been so buggy and so, uh, like I can't use the app. We tried to use the app actually, um, just to like build the studio out that we're working on and, uh, it like slowed down things so immense, uh, so immensely, like it was, it was crazy slow how like development time and build time and everything.
I think they're working on that, but, um, but yeah, I mean, so like, but, but needless to say, like it just, I couldn't, like, it was very difficult to get it working even with all the docs and like, there's so much change you have to make internally as a library. Like so, so much change. Um, that it's just like, what's the, like I'm encouraging people to like, especially for Tamagui, where it's like we're encouraging kind of like a universal world, um, for sure at some point.
Like, we'll probably support, support It just, like I said, you know, some people it's, I wanna be the best for, for web only as well. That would be, that's the ideal. But I just think it's, it's not as high of a priority for something like Tamagui where like, if anything, I think I encourage people to just not use it.
Um, because like if you're building an app, um, it doesn't even work with React native currently. Like there's no real way to make it work with React Native. And then also, um, yeah, I mean, yeah, you just literally can't do a React native app, but also even if you could, um, the only type of React native apps I would see that being good for are like very crud style, react native apps where it's like you're just displaying some basic data, um, but you're not, you don't have a list or you don't have a chat, or you don't have a, you know, like a interactivity that's, that's like.
Andrew: That's nice.Well, it's un understandable from your point of view is like trying to create these cross platform apps that like, it, it inherently only serves the web and the, like, the beauty of early React was the incremental adoption story of like, oh, this tiny little part of my page can just be react with react server components.
It's like, sure, incrementally adopt it at the root and serve where you serve your app. And it's like, oh, that's, that's a, a much bigger ask in my opinion.
[00:45:32] Cross Platform Apps in Practice
Andrew: Um, but now that we've broached the topic of sharing code between, uh, native and web, uh, how does that work Tamagui 'cause like, uh, I, I tried to do this one in a few years ago, create a, a hybrid style app, and I was like, okay, I'm gonna make one app, it's gonna render everything.
And then I was like, oh, wait, navigation and like all these different little things. Then, then the, the leading advice at the time was, oh, you just create your app for web and you create your app for local. So how does Tamagui
Nate: yeah. So, um, the way that the starters work now, um, is so you, you can share as much or as little as you want. Um, I still think that the advice of like splitting the root level views, um, is, is, is valid. Um, you know, you probably want to use React native navigation for native 'cause it has really nice native support for like, uh, you know, stack views and all these different tab views and stuff like that.
Um, and then on the web, you know, it's kind of like your choice. The, we have a starter that comes with Tamagui, it, it builds off of Fernando's work again with Salito, which basically Bridges Expo and Next. And so you still kind of like, You have a, I would say like, basically the, the world that we're in now with that starter is where you have 95% of your code, uh, shared.
Um, if you want, you could always diverge them as much as you want, but like, if you want and you can and still get a good experience, I think you can have 95% and that 5% that's left over is mostly that navigation level. But even that is nice, like salito unifies the, the navigation stuff. So like you still have the same hooks to call, like dot Navigate, um, it's just on the web instead of a stack.
It's just pushing forward a page and then you can hit back. Whereas on native, you know, it can pop in a page and you can slide back. Um, so it's definitely gotten better. Um, that story is like, I think that sort of like makes that whole thing pretty worth it. I still think there's like so much to go. I think Expo router looks very interesting, like what they're doing where it's file system routes, basically.
Like that's what I've been, I was gonna do that if they didn't do it. Um, but looks like they're doing it. So there's less incentive for me to do that now. But like, Um, you know, you can have one file system route thing and then, and then give it different layouts. Um, you know, so you can have a layout for web and a layout for, um, for native and fork them.
Um, but, uh, yeah, I mean, that's kind of the big difference I would say. I mean, obviously, you know, responsive design and touch base design, there's some, there's some things that you should always probably try and change, but, um, but I think with, with that story in place, it's not too bad. And I definitely recommend using one of the starters, um, because they save a whole ton of time.
Justin: Yeah. So, as, as with everything, there are gonna be some trade-offs, um, to taking this approach. So, and, and you've already, you've already said that you've sort of laid out Tamagui to be, you can just use this in a web project. You can just use it in a React native project. It doesn't have to be both.
Um, and I, and I really like that tack. Um, so. You know, outside of the benefits of sharing code, are there other benefits do you think, to, to using Tamagui in general? And is there a moment when you probably shouldn't use it, that you probably should pull for something else? I.
Nate: Um, yeah, lemme start with the, the second part. Um, 'cause there's definitely times when you shouldn't use it. I mean, um, you know, it does bring along. Depending on how much you use up to 30 kilobytes of, of JavaScript for the whole system. I mean, if you use the full component kit, you're, you're bringing along, you know, more depending on the components you use.
So for certain things where it's very sensitive to, uh, to bundle size, then it can be that. I mean, I think it's not bad, you know, 20, 20, 30 kilobytes not too bad. Um, but there's obviously, definitely plenty of sites where like you're just going for very clean and minimal. Um, it also depends on familiarity, you know, um, there's, there's plenty of, tamagui brings a design system aspect and like, you may not want to deal with the design system.
It's more conceptual burden. There's this concept of tokens, there's a concept of themes. There's a concept of like, uh, font you have to, you know, you do your fonts with a certain syntax that, that expects like line heights and all this stuff that kind of go together. Um, so there's, there's an onboarding cost, there's a cost of like learning all the concepts and, and there's, there's definitely more to it than like, You know, tailwind, uh, I give it the benefit that it just really does, like you have to learn that.
But uh, conceptually there is just kind of like class names and whereas Tamagui, I think it's a little bit more like you have a design system that you can customize. I mean, you can use the off the shelf one, but uh, you also can customize it, and so you'll run into that at some point. Um, and yeah, I mean, I think for very web focused projects where like you're, like if you were a studio, like an agency, you know, that's building like a, a very fancy like website and you're trying to do like scroll effects and you're trying to do like, uh, you know, crazy like animations and stuff like that, like intense animations.
Like obviously you can use class name or inline styles in Tamagui and do that. But I just think like, you know, that's kind of getting to the point where like if, if it's web only and you're expecting to go very deep into Css land, um, Do that. Another example is like container queries, for example. We're working on them, very excited to, to get them to land.
Like very excited 'cause yeah, it'll work on native, which doesn't have that concept, but we can obviously add that. Um, so yeah, there's a lot of, everyone's waiting for it, but it's been a lot to kind of figure out the syntax and everything. Um, but like, yeah, for example, like container queries, they pretty much are supported on modern browsers today.
So like, you would have to sidestep Tamagui and like that would be its own thing. You could use them, but again, you'd be using like class name and stuff. And so you do have to have that, you have to accept that there's probably gonna be some lag time if you want like, these universal concepts, um, to be fully supported, like in, in a way that works with the, the design system that you have, for example.
Um, so yeah, those are different caveats. Um, the setup too, like definitely, you know, there is some setup and so that's probably the biggest one that we need to work on. 'cause you know, I think for a lot of people they just go with what's familiar or what's easy to set up and, um, And it's, yeah, it's one of those things that's hard to, it's hard to focus on when you have container queries, you know, it's like container queries or like helping configuration.
It's always hard to, uh, to choose like the, the less sexy path.
[00:51:42] Themes
Justin: Uh, yeah. So just like some other benefits that we may not have covered so far. So we've, we've talked about, uh, the compiler, we've talked about animations, we've talked about, um, the sort of, you know, benefits of the styling system and the types that come along with that. Is there anything that we didn't cover?
Nate: I mean, I think you guys did a great job with those questions. 'cause I mean, those are really like Yeah, the, some of the stylists and benefits, animations and all that, the universal thing that, obviously the compiler I think is the big one. Um, the fact that it's, it's not just about bundle size. It's not just about, C s s, but it's also about like runtime performance.
That's like, I think a big one to emphasize. You get really nice runtime performance improvements. Um, so if your app is slow feeling, that can really help with that. Um, I think the final thing is the theme system. The, the theme system is probably the coolest part almost of tamagui. And it's, it's, we're gonna have some cool stuff coming out very soon for that.
Um, 'cause the themes, we went for power. I, I definitely like, you know, I, I kind of went deep and I've been doing these components systems for so long that I kind of knew what I needed. But, uh, the first versions of themes were like very powerful, but very hard to work with. And then we've slowly built up better abstractions around them.
We just released this thing called, uh, theme Builder, which gives you this very nice trainable a p i. Um, there's a guide on the website now that's like, kind of very nice and it walks through all the concepts and builds up to it with like diagrams and it's, it's a, I spent a lot, a lot of time on that guide.
I think it's pretty cool, but I still think almost no one's using it yet because it's. Um, I just think the Tamagui theme system that comes with it is pretty nice and most people aren't trying to fuss around with that. But we're working on these next things now, which is, um, kind of like a studio type thing where you can like visually go and create like a theme suite.
Um, and the, the power in our theme system, like I've been playing with it lately and it's getting very, very exciting. Um, but yeah, the themes, they, they can nest as many times as you want. So you can have sub sub themes that nest down. And so if you have your root, light and dark themes, but then you have like an alert or like, let's say like, you know, you have a lot of like tool tips or warning dialogues, right?
And that one's they wanna be yellow. So, I mean, what's nice is that you can wrap that with a theme that's alert or error, right? And it'll actually like re theme all the sub components in that tree. So the buttons inside of that will turn red and the tool tips will turn red and everything like it, it literally will re theme everything below that thing.
But then you can go in and there and even further nest it. Like we have this idea of inversing, which is very cool. So you can like just. Inverse any theme, as long as there's a dark and light version, it knows to like flip at that level of the tree. Um, and if it's a dark red theme, it'll flip to light red, for example, at that level.
So it's kind of cool in that, in that sense, like, I just think the theme system is, it's so badass. Uh, it's taken an insane amount of work to really get it to work. Especially like with server side rendering, like there's been so many like hydration issues and also avoiding re-render, like I mentioned, like that, like all that stuff together has been just a ton of work to get going.
And, um, so we're getting like very close, I think, to where people can go in and generate all these themes, suites, like we've been, I've been playing with it and like generating like neon this, like neon green with like bright outlines or like, you know, a very subtle like deserty look and stuff like that.
And um, and then, and I think the coolest part though is that it's not just like you can, you can also target down to the component. So like each component, if you give it a name, like it's a styled component, right? But you can give it a name so you can, you can name it like a button or something. And then it looks for that sub theme.
So if you have a dark red theme and then underscore button, it'll automatically, like, that component will try and find that theme. And, and then, uh, we have this idea of masks to generate the theme. So it's like, the cool thing is like, you can potentially go in and say like, I want my, like my red to have much higher contrast, you know?
And for all the, for all these components inside of it like this, the buttons should be like much more contrast or flip and inverse the text and all this stuff. And like, we're just getting to the point where like it's, the power's been there, but the ease of use hasn't, the ease of use is now mostly there on the programmatic side, but now it's still like, it's just hard 'cause you need to visualize all this stuff, right?
it's, at the end of the day, it's, you know, it's still hard for me to generate themes because like, at the end of the day, I need to see them and have like a good loop to like, tweak things and have all the right concepts. And so I think we've built up those concepts, um, and all the abstractions.
And now we're just kind of, um, putting together like the, the visual side of it. That's gonna be, it's very exciting to me.
[00:55:52] Studio
Andrew: So that visual side is the studio,
Nate: Good segue. Yeah. But yeah, I mean, the studio, it's an amorphous thing. I, I haven't known exactly what it is. I mean, I've known that I've what I've wanted, but like, it's been hard to pin down what it should be, especially the first version. Um, but yeah, I mean, uh, I, I finally, I think we've gotten like a lot of clarity on it.
'cause we were playing with lots of different concepts with it and trying to like, make a very advanced version of it work. Um, and I think it was actually the wrong way to, to approach it. So we've been redoing, uh, a more like step by step thing where you choose, like at each level, like, do you want dark and light?
Okay, here's your base themes. Choose the colors. Okay. Do you want more or less contrast? You can like, choose different options. Okay. And then it gives you like a preview screen and you can tweak everything. And then you can go in and apply like, Do you want these components to be more or less, uh, emphasized and like with borders, do you want the borders to be more or less?
So it's like, it's kind of cool, like now it's more of a like step-by-step theme building, uh, process. It's very like, it's got like a lot of explanations now at each step too, which is pretty cool. Like little like pointers that kind of show you what's going on. Um, and I'm very happy with that. Like, it's, it's, it's, it's a huge, like the, the old version was more like a Figma type thing where it's like, here's all your components and here's all your themes, and click around and like tweak things.
And So I even, I was kind of getting lost and like, well, okay, like, whereas this is a much more like you can import your existing one and tweak it at each step, or you can just generate a new one. and I think we're gonna start with that and then hopefully keep building up from there. Like, I think there's a lot of interesting potential integration with Figma, both import and export, kind of like integration with Figma.
I think that the studio could have, there's some storybook like directions maybe where like you can host all your components and like screens maybe even, and like, And there's also some interesting things where it could maybe run as an extension in your browser, and like you could tweak things with, within your app actually, and like change the themes on the fly as your app is running.
So lots of like, lots of like big ideas, but uh, we have to actually ship something. So this first one, hopefully is just gonna be this like, theme editor. Theme guide, guide
[00:57:48] Takeout
Justin: You've also got, uh, takeout, which is, uh, well, why don't you describe it?
Nate: but, uh, yeah, takeout is, um, that is our first attempt to make this sustainable. It's been tamagui been open source. and we've, I've been spending like nights and weekends, basically a lot of nights and weekends on it since I started a couple years ago almost.
Um, So, uh, we, we got a lot of sponsors. I've been really, really honestly blessed to get so many sponsors. Um, and we've got a couple more that have just joined, which is pretty cool, like corporate sponsors, but it's just not enough, like to really make it worth it. So we launched, um, we launched this first, I guess, attempt to make some money back.
It's called takeout and it's, it's actually really nice. It's just like we've, we've kind of built our dream stack of what exists today that we think is the best stack for today in terms of like realistically deploying a cross platform app, um, with everything that you need. Um, so it's mostly based on super base.
It's building off the starter that you get, the free starter that we have. So next JS and expo, monorepo kind of salito all that stuff. And then we added on superb base with all the different auth and um, and database set up migrations and all that stuff set up. Um, it's got a bunch of screens set up too.
So you have, you have pro, you have like login and forgot and all that different off screens. That are universal and adapt, you know, it's got onboarding screens, it's got a bunch of stuff, uh, settings and account screens. We, we try to try, try to cover like all the stuff that you basically need for any sort of app that has like a user system.
So it's got all that user system stuff, including all the setting screens, which are pretty nice, like light and dark settings that get persistent and, and, or system or whatever. And like all the different like screens there, account edit, upload profile picture, um, and uh, stuff like that. So, and I think it shows you how to use like r l s like and how to secure them.
Um, ' cause that's all set up for the, the profile screens and stuff like that. So it's great. I mean, yeah, I mean if I start a project, um, of my own, it's where I would, it's where I would go And, um, it's do actually, it's doing pretty well. Like, I, I'm not gonna lie, like I was kind of surprised, like, I don't know, most people don't sell starter kits.
Uh, most starter kits are free. And, but I mean, we put so much work, like we really did, um, put a lot of work into making it really nice. And I think it's unique 'cause like tamagui agree is kind of like there's not much else that really is delivering on this cross-platform, um, sort of dream. And, um, and so yeah, I think people who are like interested in, in building a native and web app or seem to be responding, which is pretty cool.
We'll see how, you know, after the hype dies down. Uh, but I do wanna also give a big shout out to, to Ali who's been, he joined at the beginning of this year as basically full-time. And he was a contributor. That was, I was giving him some of the sponsorship money to help and he's just been amazing. Uh, just a really, really great guy.
Um, so easy to work with and, um, just consistently is outputting like really great work. And he's led basically takeout, uh, 'cause you know, it's much more efficient for me to be dealing with all the day-to-day bugs and stuff. So I, I just basically sit there and like, he tells me bugs and takeout or. Uh, people tell me bugs that are happening all over, and I'm just trying to like, keep things afloat and then, uh, help him here and there with like, decisions and like different little things and takeout.
But for the most part, um, he, uh, he drove that project and, uh, yeah, it's, it's been great. Like, uh, I, I feel like it's, we're sustainable, like more than sustainable now. So hopefully that keeps going. And we're, we're thinking about adding on more stuff. Like we, we, we got all of Google fonts for example. We made like a very long script that like subsets them and like converts them into like a nice bundle for, for native and for web and like gives you, there's even a C L I that you just run a command and it shows you like, okay, copy and paste this here or there and uh, and now you're set up.
And so we did that for all of Google fonts and we also did that for all of the icons on icones, I think is what it's icones.jss.org or something like that. What is it? I'll have to figure it out. What? Kase? Yeah. icones.jss.org. Um, so it's like 15,000 icons or something like that across like 50 or something like that, icon packages.
So it's kind of cool. You can plug in, you know, unlimited icons and a bunch of fonts, but we're gonna keep, I think the plan is to just keep adding on and trying to make that value really high of like, um, more cool fonts. Um, more like more theme packages. Definitely like very interesting theme packages. Uh, 'cause we have a couple extras there, but we can definitely add on more.
And there's a lot of things like testing. I think we're, we, we got, um, storybook working for native and web, but like, testing could be a lot better set up I think, and have a really nice clean setup. So yeah, that's takeout. Oh, and the, the bot. Yeah, obviously I think that's one thing that's like, kind of cool is like it sends updates.
Um, so like, Um, we try to structure it in a very, in a way that's like, for example, we don't like nest your providers. We, we, we do them in a way that like, lets you do them flat. We try to like, kind of design the repo to be mergeable and like, so you can like, stay in your areas, but the infrastructure stuff is hidden into like these different areas.
And so we've sent out like five or six updates since we launched it a few weeks ago. And so far so good. Like we've had no complaints. A lot of, a lot of, uh, people are, are like giving us good reviews. So, um, there's been like, we gotta improve the granularity, I think of the bot we've been sending too big of updates almost, but, uh, it seems to be working so thats cool.
Andrew: Yeah, it's pretty cool. The, the value proposition is definitely there with all the stuff tamagui provides. And then like, the know-how of just running a repo like this paired with the updates. Like, I'll admit, I've been eyeing it for, uh, one of my projects i wanna do
Nate: Nice.
Yeah.
I'll take that.
Justin: Yeah, definitely
definitely definitely high value here. I mean, you know, it takes, it takes a long time to build Like this this
Also the takeout website is excellent. It's so good. It's so good. I love it. tamagui too. Excellent They're so
Nate: Thanks man. I had fun with, with, takeout. That was a really cool project. I had to tone down a lot of the graphics 'cause like we, I had like a lot of graphics going on in that header and I think I removed like most of them unfortunately, 'cause uh, yeah. But, but browsers are so good. Like shout out to, um, mixed blend mode, like that's a, such a cool new c s s thing and like clip path.
And then like WebGL, it's like you have like mixed blend running on top of a SVG on a custom font with like a WebGL thing rotating behind it. I mean, it's pretty crazy that that works these days.
Andrew: It is, yeah, the, the hard to catch up with the web.
[01:04:04] Tooltips
Andrew: My first tool tip of the week, uh, is another component from the developer that did saunar the like, uh, react component for Toast that has a really nice A p i, I'm pretty sure he works at Vercel. This is a, uh, similar component, uh, coded in the Radix style where, uh, it's a drawer and it has all the mobile interactions, like you can drag the header and dismiss it.
So I just love little components like this and I thought it'd be a nice thing to bring up given the conversation we just had. And you guys have something similar in, uh, Tamagui, right?
Nate: Yep. We have a drawer that's been hard fought. It's one of the harder components to build. Yeah. The, the, those drag interactions are no joke. Um, so yeah, I saw a vault too. It's very, very cool.
Andrew: Next we have Libre Caslon condensed
Justin: yeah, I, uh, I, I saw this font get advertised on Twitter. Um, yeah, so I am always down for a new font and especially a free new font, and this one is just gorgeous. Um, I have definitely, uh, scope this one out for some use cases, but yeah, I don't know. If you are looking for a new font, definitely check out this.
Andrew: So I can put something other
than
enter on my websites.
Justin: yeah.
Yeah. It's a real, I mean, it's a, it's a phenomenal serif font and, and I also specifically enjoy condensed fonts. especially for headlines, um, I feel like there is a tendency a lot of times to take up too much space and I like, you know, being kind of very punchy with it. So this is a really good one.
Nate: Well, mine feels a little outta place. It is not. It's not as much of like a tool tip. My other one is though. My other one is, uh, I just have to shout out G Q D every chance I get um, to me it's the thing in the world. It's a GraphQL librant, that you just write your queries like with a hook, like use query, and then works backwards to the GraphQL query.
I use it on a, yeah, that's a good example right there, that playground. But like, I use it on a large app and it's literally the best data. Like if you want an alternative future to react server components like this, to me is, is that it's literally the most beautiful a p i I've ever seen for fetching data.
Uh, I think if it was paired with a really nice backend thing to, to have your graph be pretty easy to build, which I, I have some ideas around. Um, but yeah, I just, it's such an underloved library. It's so well done. Um, I've, I contributed to some of its development early on. Uh, yeah. So see myself there, but, uh, but yeah, I mean, um, They just, they deserve much more love.
Very cool stuff.
Andrew: So is it like doing some crazy stuff to construct that GraphQL query
Nate: It is, yeah. There's some interesting details to be discussed there, but like, yeah, it basically is proxying and reading what you're reading and, and mapping that back to a, uh,
graph QL query.
Justin: Is this similar at all to, uh, G Q L Ss?
Nate: Yes. its fork of gqls that I I actually was was using really slow and then I, it was a whole story, but the developer of GQLS was not, um, cooperating and like blocked us from the repo and stuff like that. It was, we were trying to work with him anyways, we ended up just, uh, renaming it because that was our only option.
But G Q D is literally a fork. It was rewritten actually, um, to be like very fast. So it's basically a fast g. GQLS. But yeah, the guy who, I mean to, to his credit, the guy who came up with, it was like 16 at the time when he released it. And it's such a, such an impressive library for someone at 16. It's like, it's because it's not only is it a novel idea, you know, it's not just like, so there, there's people that do impressive technical.
It's like, it's very hard to find the intersection, I think of hard tech and a new idea. Like I see a lot of kids that are like, oh, I, I built a recursive, you know, optimizing, compile, whatever, like a descent, this or that, you know, crazy thing. But it's like something that's been done. Um, but to have a new idea and then to like actually implement it, like shout out that, that was a very impressive project I thought.
Yeah, I remember one of the things that when were doing React native at artsy in particular, There was this always cases where, you know, you would be, you'd leave a field and that field would still be in the query when you'd removed it from the UI or something like that. It's like we had a thing where we'd set up type safety or something so would map up so we'd like know if we were querying it, but the opposite was not always true.
It's like if we removed it from the ui, are we even still using this thing anymore? And, uh, this is really great because it's like you just think about the UI and it sort of builds out the query for you and that that's super powerful.
Andrew: Okay, next up we have, uh, mine, uh, Postgres Language Server. This came out from Superb Base, uh, and they implemented a language server just for Postgres for VS code because apparently, All the other SQL language servers aren't just Postgres. So, uh, I just find this really cool that, uh, they didn't really have to do this, but they took the time to implement something that's pretty complicated and everybody can benefit and not just superb base users.
So, uh, shout out to them for that.
Justin: They are pretty deep in the Postgres ecosystem though.
Andrew: Next up we have
D X O S.
Justin: Yeah, so my, my friend Jess Martin has been doing a little bit of work on this, and it is a way of building distributed local first software. So they have like a little demo on their homepage here. Um, where, yeah, I mean, essentially all the things that you can think of if you're trying to make like a sink engine, kind of like linear did, but maybe not exactly that like that.
But yeah, so it's just a, um, sort of a toolkit for, for building, yeah. Uh, multiplayer, uh, peer-to-peer, local first applications, and they're doing some really good work there. So if, if that sounds like something you're trying to do, then, then check out this library. It's, it's really interesting.
Nate: That is really cool.
Andrew: And last up we have another font, uh, uncut.
Nate: little bit funny name now that I think about it. Uh, but uh, yeah, so it's actually not a font, it's just a collection of fonts. But I found this while working on takeout. It's actually where I found the font that we use called cherry Bomb. Um, the, especially the title I think, or the display section,
I just found this recently. I don't dunno how old it is, if it's old or new, but it's got, um, just cool stuff, like different looking fonts. It's like a really nice collection.
I'm probably gonna try and like add it into our tamagui, you know, c l i script or thing. 'cause it's, it's, it's like a nice, nice suite of fonts.
Andrew: yeah. There's, uh, some, wacky ones in here.
well that wraps it up for tool tips. Thanks for coming on the episode, Nate. This was a really fun time getting to learn about tamagui and all the different considerations you have to make when building for platforms.
Nate: yeah, thank guys so much. Uh, this was, uh, it was a great conversation. You guys brought up all the good points, so I appreciate that and it was really nice to, uh, to chat.
Justin: Yeah, and massive respect. I, I know having worked on something similar for a short time, I know this has been a ton of work, so it's really cool to see what you built.