
Radix UI is an open-source library of React components. Its “headless” primitives handle the complex logic and accessibility concerns—like dialogs, dropdowns, and tabs—while leaving styling completely up to the developer.
Loading summary
A
Radix UI is an open source library of REACT components. Its headless primitives handle the complex logic and accessibility concerns like dialogs, dropdowns and tabs, while leaving styling completely up to the developer. The project emphasizes usability, accessibility and composability and has become a vital part of modern web dev, in part because it forms the foundation of SHAD CN UI. Chase Strickland is a software engineer at WorkOS and a maintainer of Radix UI. Chase joins the show with Nick Nisi to talk about Radix, its primitives, Radix relationship with Shad cnui, the evolution of web primitives, and much more. Nick Nisi is a conference organizer, speaker and developer focused on tools across the web ecosystem. He has organized and emceed several conferences and has led Nebraska JS for more than a decade. Nick currently works as a developer Experience engineer at Work os.
B
Hello and welcome to Software Engineering Daily. I'm your host, Nick Nisi and I'm joined today by Chance Strickland. Chance, how's it going?
C
Good, how are you, Nick?
B
Oh, I'm doing fantastic. I'm ready to talk about Radix. Radix, however we want to pronounce it, but it's a very exciting project. But before we do, why don't you tell us a little bit about yourself.
C
Yeah, my name is Chance Strickland. I live in San Diego, California. I am a software engineer at Work OS and yeah, working on all of our front end things and still maintaining Radix as well. So that's kind of like my split of the day job. And then outside of that I have a dog and live with my wife in North Park, San Diego like I said and like to play music. That's a pretty good holistic scripter, I think.
B
Yeah. What instruments do you play?
C
I got some drums behind me. So yeah, I don't know. Is this going to be a visual podcast? Can anyone see this or is it just audio? If it's just audio, I will make sure I don't make any more visual references. But yeah, I play drums. I've also got several guitars back here, so yeah, I dabble in a few things.
B
Awesome. Nice. Cool. Well, why don't you tell us what Radix is or Radix and how you pronounce.
C
I guess first we can start by pronunciation because I've always said Radix but I hear people all the time will come up and say, hey, I love Radix ui. And I'm like, that's cool. And I don't say anything because I don't actually know if I'm right. The project was started by a team of half Americans and half Brits. So, like, between the accent and potential pronunciation differences between the two, I don't know, actually. I just have always said Radix.
B
Cool. Yeah, it's kind of got that Veit Veet vibe there.
C
Exactly. Yeah. You can call it whatever you want.
B
That's totally for sure.
C
It'd be more fun if we said it differently the entire time.
B
I will probably do that, but without even trying. You keep telling me and then it immediately just goes through my head. But that's okay.
C
Totally fine.
B
Yeah, it's a really cool project. Do you want to describe what it is?
C
Sure. Well, it's actually a few different things. So Radix is kind of like this umbrella of a few different projects. The one that most people know about and think about, I think, when they think of Radix, is the primitives. Radix Primitives is a group of composition first compound components that has been used for quite some time, sort of encapsulate different patterns, common patterns you see on the web that are generally somewhat complicated to implement yourself and customize. Some of them build on top of web primitives, and some of them predate some existing web primitives in some ways. And we could talk a little bit more about that. But essentially it's a component library for. For building on the web. So if you need things like a dialogue, if you need, you know, a tabs interface, if you need an advanced customizable select dropdown or some other type of dropdown menu, like, we have all of those components ready to go out of the box. We tried to build them in a way that is as accessible as possible so that you don't have to think a ton about accessibility and also just general usability. We put a lot of work and effort into making the experience very seamless when using Radix components. And we also make sure that they are style agnostic. So that's kind of it in a nutshell. And then like I said, we have a few other projects as well under the Radix umbrella. We have Radix Themes, which is also a suite of components, but it sits at sort of a higher level in abstraction. So it is completely styled by default and has a themable API so that you can get up and running with your app a lot more quickly without even thinking about styling. And then you can customize it through the Themes interface. And then we also have Arraytex colors which is a very meticulously designed color system for very seamless switching between dark and light mode in a way that is aesthetically pleasing, but also designed again from an accessibility first approach, so you don't have to think as much about things like color contrast ratios. And then we also have Radix Icons, which is a suite of icons, as you might imagine. So those are all the projects under the Radix umbrella. But, yeah, most people, I think, are going to associate us with Radix primitives.
B
Yeah, I think so. And that's probably how I have come to know Radix as the primitives themselves. But I want to talk about each of these pieces, but let's just start with the primitives. There is another way to classify them, I guess. Would it be safe to call them headless?
C
Sure, yeah. I like that term.
B
Cool. And the way that I came to that term, or came around to liking that term, was because on a project I was working on, we were using Material UI and everything kind of looked materially, and we wanted to get away from that and kind of have our own stamp on the design. And Radix Primitives seemed like a really good way to go with that, because they really didn't give us any kind of style by default, just with the primitives, so that we could apply our own. But we weren't missing out on all of the benefits of not developing these components ourselves. And that's in my mind, like all of the accessibility features and browser compatibility.
C
Yeah, no, that's absolutely correct. We want to give you maximum flexibility in terms of the presentation of the components, but the underlying patterns should behave similarly across the board, across different browsers, different assistive technologies and how they interface with these things. Those experiences need to be somewhat consistent, but the look and feel is obviously going to be determined in large part by your brand.
B
Now it just naturally makes sense to have those primitives and then also to have like a set of designs on top of them or themes on top of them, which gets into the themes part of that. And you said that they're styled by default, so this would give you like a kind of a natural Radix look and feel if you use those. But then they have a themable API. So how customizable is it from there?
C
Yeah, it's pretty robust. You can actually do quite a bit with it. If you go to radix-ui.com you will be greeted by the Radix theme splash page and there are actually live examples that you will see. It's like A carousel interface where you can reset the theme of the homepage itself, which is kind of neat, but it just sort of showcases some of the flexibility of Radix Themes. Now, that being said, it is opinionated, right? Like any freestyle library is going to be opinionated. You mentioned Material ui. Very opinionated. It tries to strike somewhat of a balance because you do want ultimately to decide some aspects of the look and feel. But if you are just trying to bootstrap a project and get it off the ground and don't want to think too much about the styles, Raix Themes is going to look really nice out of the gate. Then later you can come in and change fonts if you want, come in and change your primary colors. It uses Radix colors under the hood, so you can set a single primary color and get an entire range of colors generated from that, which is quite nice. And again, it just sort of takes away some of the mental overhead of thinking about things like color contrast. And of course it's built on Radix Primitive. So again, accessibility, sort of top of mind there. Usability is top of mind. So all of these pieces play into Radix Themes and as like our higher level tool for building apps on the web.
B
Very cool. I love that, that you can just start with a color and go most of the time that's like what you want at least to get started is like I want the brand color and mix and match from there, but also have good contrast between text and background and things like that. And so really nice. You can start at any level and get going and then kind of customize to your heart's content.
C
Yeah, absolutely.
B
So I'm just curious. You've got the themes which naturally out of the themes would come the colors, right? And icons. How are those picked? Like what goes into doing this? Because honestly, this is like something that I can't comprehend is like picking the right color and then a complimentary color.
C
That's a great question. And honestly, it's something I don't really comprehend. So just to be completely clear, I didn't build either of these libraries. Sure, maintain mostly primitives and I do like still maintain these libraries, but the underlying libraries or the beginnings, the origins were not me and I don't have the meticulous, obsessive compulsive tendencies to like design an icon suite that is like the way that these things are optimized is actually pretty incredible. Like most people don't think of icons as this like really complex thing, but if you want your app to look really consistent across the board. Things like line weight and face sizing and how each icon scales up to different screen sizes and how different icons appear in relation to one another. All of that matters a lot more than people realize. Like, your average person looking at a web app doesn't notice that the icons are slightly different, but they notice something is off, right? Like, they can't pinpoint it, but they know when something looks good, and they know when something doesn't look good. And to make the thing look really cohesive and really good, you obviously need a lot of cohesion between the small little details and small elements. And so the icon suite is meticulously designed just for that. It was originally designed by. He no longer works for Work os. His name's Calm, but, and I apologize, Colm, if you're listening, I don't remember his last name. I'm going to have to look it up because I do want to plug him. Starts with a T. But anyway, he and a guy named Vlad on our team, I think co designed those. And yeah, like I said, really, really well done. I don't have to really touch him too much anymore, but we do have a couple new icons in the works internally at work os. So anyway, rambled enough about icons. Color system is kind of the same thing. Like, I didn't build that myself either. And again, I probably could if I wanted to sit down and spend that much time on colors, but that's just not what I'm interested in. But it is pretty incredible, actually. It's a lot harder than people realize. And that's kind of a theme with Radix. Like, everything that we do presents as fairly simple, but then once you peel back the onion a little bit, there's a reason people don't want to do it themselves. It's actually very hard, a lot harder, a lot more time consuming than people really need to be investing in most cases, when what you really need to be doing is spending time on your product. And so you want tools that help you spend time on your product and not waste time thinking about color scales. And that's really what it comes down to. So, yeah, I try and maintain it as best I can. We have some ideas on how to improve both of these libraries moving forward, but the core underlying piece of it, which are the icons and colors themselves, are mostly sort of bakes.
B
Very cool. And yeah, that's a great point about. You can just go down so many rabbit holes on any one of these components and spend so much time there. And that's not actually contributing to the overall product that you might be designing. So it's great that these exist for that and give you like, full customizability in terms of styling and how it looks and how it feels. I do. I have so many questions about the primitives themselves. I guess first let's talk about what they're made in. Are they React components?
C
Yep, everything is built around React, so if you use React, awesome. If you don't, I'm sorry, we don't have anything for you. But yeah, they're all React components. We had discussed in the past, like sort of expanding this and maybe taking like a web components first approach and then making those extendable so that you could pull them into a framework of your choice. But ultimately React is where most of the users are, and it is just sort of like we want to meet the users where they are and that's our approach. And of course, at work os, we use React internally extensively throughout our stack. So yeah, it makes a lot of sense for us to stick with React.
B
Very cool. Yeah, React is definitely where people are at when it comes to styling, whether it's directly on the primitives or through like the themable API within the themes. Are they like the same in terms of how you would do that and does that support, like, any styles that you might want to use or any styling frameworks?
C
So like I said, Themes is opinionated. It's also customizable to the themes interface. But my favorite thing about Radix Themes, actually is the fact that under the hood, everything that powers Radix themes is just CSS. So there's no special runtime, JavaScript or anything at play to prevent you from styling anything in your app outside of the themed interface. So at the end of it, what you do with Radix Themes is you essentially import a few style sheets, and then once you do that, you have all of the class names mapped to the components you get from Radix Themes. But at the end of the day, it's all just css. So overriding Radix Themes or even selectively including certain style sheets, we have like different levels of abstraction for our style sheets. So you can only import things that you want from our layout components, like Grid Flex components. Like, we have different layout specific components. If you only wanted those, you can only import that and start building your own color system on top of it. If you want the whole kitchen sink, you import all the style sheets. But then you can go and you can target overrides, you can reset certain variables that we might set under the hood. Like it's extremely flexible in that way because if you write css, you just write more css. And because of the cascading nature of css, it's not terribly difficult to override things. But we obviously don't necessarily think you should have to be overriding too many things, because that's kind of the point of an opinionated library. But it is flexible in that way. And I think of the CSS only approach as giving you a very simple escape hatch.
B
What if you're afraid of the cascade like me, and you just use Tailwind?
C
You know what? That's fine. I don't have anything. How many people do you want to upset in this podcast is the question. I think I don't know why the Tailwind thing is so polarizing, but use what makes you happy. I will say like Tailwind is at odds with Radix Themes, but they are two different paradigms for solving similar problems in some ways. Or really, I guess how I would describe it is Radix themes as half primitives and half something like Tailwind. Right? Like half of it are the components themselves, which obviously Tailwind doesn't provide. The other half was styling, which Tailwind does provide. And they have two very different approaches to styling. And so I would say if you are using something like Tailwind already and you're using it extensively through your app, may not be the best fit to then go and grab Radix Themes. But what's great about Radix again is we have other levels of abstraction and you can go grab Radix Primitives and then you can slap whatever Tailwind classes you want on any element you want. And at that point it's just Tailwind styling and have a blast with it. We don't really care, so I don't really care. Some people care. A lot of people care. I don't know. It's like it's one of the most polarizing topics. I feel like anytime it gets brought up, which I find odd. As someone who loves CSS and thinks Tailwind is a great tool, I don't really understand the polarization. But I agree, use what you want.
B
Yeah, I feel like Tailwind taught me a lot about CSS instead of taking away from it. So that's good. Overall.
C
Capital One's tech team isn't just talking about multigentic AI. They already deployed one. It's called Chat Concierge and a simplifier in car shopping using self reflection and layered reasoning with live API checks. It doesn't just help buyers find a car they love. It helps schedule a test drive, get pre approved for financing and estimate trade in value. Advanced, intuitive and deployed. That's how they stack. That's technology at Capital One.
B
I wanted to circle back to something that you mentioned, which was some of these components predating some web primitives. Can you give an example of one?
C
Oh, sure. So dialog is a great example where we now have a dialogue element that's just a raw CSS element, the Radix primitive. When we first started Radix, I believe dialog was technically a thing, but it wasn't super customizable. And I'm pretty sure at the time it was fairly buggy or incomplete implementation in probably Safari. I don't remember exactly, but it was technically there in some capacity, but it was not robust enough for you to really realistically be able to use it in a complex web app. And that's also kind of a common theme is that there are cases where certain elements that exist on the web are usable and functional in sort of simple cases, but as the complexity grows and the needs expand, but then you might need to reach for something a little bit more customized. And so dialog's one example of that. Obviously HTML has a select element that's been around for ages, but we all have tried to customize those and we understand how painful it can be that is actually changing. By the way, there are new elements that have been introduced in HTML specifically for customizing the select. And that is also really exciting. I can't remember offhand what those aprs are, so I'm going to check that out. But yeah, it's pretty cool what the web can do for you these days that in the past you would have needed a ton of JavaScript to replicate that behavior. So those are two examples. And oh yeah, collapsible is another great one. Collapsible just essentially being an element that triggers a collapsible section and toggles it on and off. We now have details and summary elements in HTML, so you rarely need to reach for JavaScript for that. So these things are all still really useful and robust. But yeah, the web's come a long way in the last several years.
B
Yeah, for sure. Do you anticipate like, I guess when that happens, when the web catches up to something that's existed in Radix for a while, I imagine that it might lead to like, I mean, you don't have to adopt it, I guess is the answer. But like, if you wanted to adopt it, would it lead to like breaking changes or do you just kind of keep your own separate implementation of that? How do you approach it?
C
Yeah, so it totally depends. That's the answer to every question, right? It depends, but it really does. Like, it depends on a few things. So one thing that I always look for in these new web primitives is how flexible and robust are these primitives. Like, in some cases they may be completely adequate for building the most complex web app you can imagine. Now we build reaction components. React generally is something you would want to reach for in a more complex web application context. A little bit more rarely, I'd say do you want to reach for it for something like a marketing splash page or a blog. Things that are totally fine to build with web primitives and don't require a lot of advanced use cases. I would say just go with web primitives and save yourself a lot of pain. And JavaScript, in more advanced applications like the one that we work on at work os, they're just not always robust enough to handle those cases. And the web is improving on that front. But I still need to check out like, can these web primitives do everything that Radix can do today? If the answer is yes, maybe we could either phase out the component altogether and recommend people use web primitives, or we could build our primitives on top of the web and pull out a lot of our own custom JavaScript that we need to write to maintain really complex logic. So it really just depends on what the element is that we're talking about. What are these new web primitives actually capable of? And how much value can we still provide you with Radix, I want to.
B
Shift gears a little bit and talk about you and your journey into maintaining Radix. Can you give us that story?
C
Yeah. So before Radix, there was another React library that was actually fairly similar in its goals and design, and it was called Reach ui. And one of my very early projects, I was a full time freelancer for several years and I was working on various apps of different sizes and scales and at some point caught wind of this really cool new thing called React that everyone was talking about. Didn't really know much about it. I was just slinging jQuery and CoffeeScript at the time, doing my best with what we had. But there was this really new, interesting library that everyone was talking about and I decided to check it out one day and I've not really looked back. So I've been knee deep into the React ecosystem ever since and I don't even remember what year that was, but it was pretty early in REACT days. So I kind of just sank my whole career into that. And as a result, you're building these applications for me as a freelancer, I was building all kinds of things. Like I wasn't working on one singular product. I was just sort of helping different teams or helping launch products, whatever the case may be. And so there's a lot of different things that I'm working on week after week. So I inevitably needed to find a lot of different tools to help me do that job efficiently. And over time, React became more widely adopted. I'm starting to see a lot of third party tools and libraries pop up around React. That made my job a lot easier. So as time goes on and I'm looking through all of the different tools available to me, I stumble into this library called Reach ui. And it was super helpful. It provided a lot of similar components that you'll see in Radix today. Things like dialogues, tabs, menu button dropdowns, that sort of thing. And just little pieces I could grab and stick into my code and then make them look however I wanted to and just build my product a lot faster. And that was exactly what I was looking for. What was also really cool about Reach UI was its composition model. And this is something that really, it's sort of the core behind why React took off in the first place. It's just the underlying composition model of React itself. And Reach UI really leaned into that composition model and it gave you different pieces of React components rather than trying to stuff everything into a single supercharged component, like a library some people might be familiar with from back in the day and may still be maintained. I don't know. It was called Downshift. This is a really popular library that you would grab and it would give you the ability to style a complex dropdown select component. Right? But it was very powerful. But the API itself was kind of clunky to work with because it was a custom. Dropdown ultimately requires that you have a lot of different elements on the screen. You're going to have the trigger, you're going to have the list itself, the popover that the list is inside of the items. And it just sort of gave you this big fat component with a bunch of render props that allowed you to sort of customize things. But it was just really clunky to use. And Reach UI addressed that kind of thing by giving this composition first API where the root of the component might provide some context to underlying components, and underlying components are directly mapped to one or two different elements, but everything is sort of low level and composed by passing children through your other components, which that's just how React was modeled in the first place. And so it made a lot of sense to me and it also really impacted on how I built components in my own apps. So the things that Reach UI didn't provide to me, I needed to build myself. But as I was building them, I would think to myself, how would I build this if I were building Reach ui? Because that design just made a lot of sense and it made things really easy to maintain. And so the first component that I remember building that way was an accordion. Reach at the time didn't have one and I needed an accordion for a project and so I sort of just built it the way that I would imagined. Ryan Florence would have built it into Reach. And I just happened to be at a conference some years ago that I popped into React Rally and at the time it was still being maintained by Ryan Florence and his business partner Michael Jackson. And I was chatting with Michael just casually not looking for a job at all. I was perfectly happy as a freelancer. But we were talking about Reach and I was like, oh yeah, like I use Reach and it's great, I love it. And I even build like some of my own like Reach like components sometimes and I've got my own like little mini Reach extension library that I've been working on. And he was like, oh, let's look at it, let's see it. I want to see what you're building here. So I pulled it up, I showed him my little accordion component and how it was modeled and he said, well, how would you like to work on these things full time? I said, well, that sounds awesome. Why would you want me to do that? It's like, that's kind of a, it's a weird thing. We weren't selling it, so I didn't really understand like open source business models at the time. But yeah, they brought me on and it was a great experience. I got to be the full time maintainer of Reach UI for a few years. Then the pandemic happened and the sky fell. The entire funding model of the company behind Reach UI was in person training and that dried up like very quickly. So they unfortunately had to let us go. And I was sort of off in La La land looking for my follow up gig. And thankfully right around that time, a company called Modules was working on this new library called Radix. And they knew what I was working on because they looked at Reach UI a lot for inspiration on the design of Radix. And so the code that I was writing was very visible to them. And as soon as they found out I was laid off, I basically had an interview within a few weeks because they wanted me to come work on Radix. So that was my end there. That was really great. And then yeah, it's one of the early maintainers and builders of the Radix project. And then fast forward to whenever it was that work OS acquired the Radix team. I actually like went off and worked for a different company and helped build Remix and then that got acquired by Shopify and a lot of other stuff happened in my career but ultimately came to work OS and they were like, hey, why don't you maintain Rafes again? And I was like, that's cool. So like just came full circle. So anyway, that's my spiraling rambly story about how I got here.
B
Very cool. Since you mentioned it, I'm looking at Reach UI and I hadn't used this. I've been around React forever, but I've not used this before. I was immediately drawn to the component component and just looking into what that is.
C
Oh yeah, so that's a funny one too because Component component, well a. It's a ridiculous name, but Ryan is kind of a ridiculous person sometimes, so I really enjoy his sense of humor. But yeah, Component Component was interesting because what it essentially is this predates Hooks. So you can sort of think as Component Component as the way to sort of like access contextual logic from parent components in child components before the Hooks world. Right. So prior to Hooks, there were a couple of tricks we had in the React world to essentially like implicitly link two different components. And what I mean by that is like the traditional way to feed data from one component to another in React is passing them via props. Right. Like we all just pass props along. But when you have these like highly coupled components, like a select. Right. Like a select is always going to be coupled in some way to the thing that opens it and it's going to be coupled to the list of select items. Right. A lot of times components are just inherently linked together and props are clunky because you end up having to pass down from the top component down and like essentially prop drills, the term we came up with back in the day where you're just like drilling props to multiple levels. And with highly coupled components it was just simpler not to have to do that and be able to access contextual data from some parent component. And so there were different patterns adopted for this. We had higher level components where you could basically create a wrapper function that wraps one component and then just passes along certain props from some parent. That was fine, but it was a little hard to follow what was actually happening in the code. You would end up with like 20 different higher level wrappers and then peeling that onion back became pretty tricky. So this was all pre context. So react context changed a lot of this, but also react hooks obviously changed a lot of this where you could use the context directly without having to again prop drill. But before all that, Ryan decided he was going to try and solve this problem in third party land and he came up with Component Component which is essentially this higher level component that allows you to access the lifecycle methods of a react class component or state setters of a parent component in children. So yeah, it was kind of like his initial idea of how to solve this problem before hooks came out and solved a lot of these problems for us.
A
Tired of babysitting autoscalers and overspending on Cloud costs meet Thoris the platform that makes engineers heroes to their finance and business leaders. Thoris intelligently manages Kubernetes clusters automatically, right sizing and scaling workloads while preventing downtime from traffic spikes. It anticipates usage and capacity needs so systems stay fast, reliable and efficient. Without constant tuning. Teams using Thoris cut cloud spend by 40 to 60%. Thoris predicts compute and GPU demand before it happens, keeping performance smooth and costs in check. Stop wasting compute and guessing your resource needs. Let Thoris handle your auto scaling so your teams can focus on building. Find out how much you can save with Thoris. Visit Thoris AI and try our cloud savings calculator. Is your AI model taking weeks to train or is it too slow for real time inference? Fixstar's AI Booster is the acceleration platform that solves both. AI Booster automatically analyzes and optimizes your entire AI pipeline. The result? Dramatically faster training up to 5 times faster and compute costs slashed by up to 80%. Trusted by major companies including Sony, Honda Mobility. Stop waiting on your hardware. Visit fixedars.com to learn how.
B
When I was looking at it gave me the vibe of context like that. Just seeing the set state being passed down is kind of what gave me that I suppose. But also on this site I see that it's copyright react training which the company you worked and then they kind of those folks went on to do remix as you said and you had some run in with that and so I have to ask given that this is a REACT library and Remix's future, as they've kind of started talking about their plans of potentially not going with REACT for their rendering. I don't know if you had any thoughts or things on that. Just like, I think about it in terms of, like, there's a lot of these mature component libraries now that you won't be able to use if you're using the new Remix. I'm not trying to, like, make you say anything controversial or anything. I'm just curious if you had any thoughts on that.
C
Sure, yeah. And I try not to be too controversial. I don't have a lot of hard opinions in this world. I have opinions that are. What is the saying? Strong opinions loosely held something along those lines anyway, so I try to keep an open mind to most things and same thing goes for this particular thing. So, yeah, a little context here. The Remix project started shortly after the pandemic, when they had to lay the team off and we're out of work. And they were like, well, now's the best time we're ever going to have because we have all this open, this free time. What are we going to do with it? Now is a good time to work on this framework that we've been building cooking around in our heads for the last several years. Because Remix really was a series of ideas that Michael and Ryan just had, but never took the time to build it. And now they had the time and so they thought, why not build it now? And so, yeah, it started as a React framework and solved a lot of problems that they found lacking in other solutions at the time. And, yeah, eventually I joined the team and it's a small, scrappy little startup trying to work our way to the top. And yeah, we built a framework that caught a bunch of people's eyes, got a good amount of users pretty quickly, and a lot of people really liked the model that we had provided. And they liked it so much that ultimately it was acquired by Shopify. And Shopify has continued to invest in it and build it out. And it's been through a couple of different major versions at this point. But as you might know, or listeners may or may not know, at React conf. I want to say it was last year, the year before Ryan got on stage and told everyone that Remix was taking a little nap and the world panicked. Everyone thought, oh my God, they're killing Remix. This is like React router V4 all over again. What are we doing here? And what he actually meant, it may have been a little clunkily delivered. But it wasn't that they were killing Remix. It was that Remix needed to fundamentally change. As much as they really liked the model, they had built on Remix, Remix itself as an idea could have been a lot more. But what they didn't want is to pull the rug out from people who were using Remix. They also thought there was still a lot of value in the model that they had and they wanted to build on that. The thing about Remix, though, is that it was built entirely on top of React Router. Like the, the heart of any framework really is the router. And React Router was sort of the underlying tool that powered most of what Remix ultimately was. So the entire routing system was React Router. And they over time they started adding new features to React Router that were originally Remix concepts, to the point where at some point you looked up and you said to yourself, react Router just looks like Remix, except for there's no server, like it's just a client side library. But the actual APIs look a lot alike. And at that point, what is Remix even? Remix is essentially a compiler that allows you to build a React Router app and target a server and a client. Why wouldn't React Router just do that for you if it's already got all the other features? Right? And so essentially they just ported over everything that was in Remix into React Router and started referring to React Router as a framework because it was, it was suddenly a framework super power framework. And it looked basically the same as the prior version of Remix with a few new major changes. So React router V7 was essentially what Remix, but now you had a naming problem, and naming things is hard in this field of work. So you had a naming problem, you had a messaging problem. So how do we solve that? Well, again, I go back to the fact that they still had a lot of really cool ideas for Remix. And I just want to be clear about something really quick. I had left the company at this point, so I don't have any inside baseball knowledge of what happened at the point when they decided to do this fork in the road. So I'm, I'm just making guesses alongside the best of us. You know, I know the guy still, so I know a little bit, but I don't have any special knowledge here. So I'm just riffing. But what I sort of feel like happened is the Remix name and the Remix idea, the underlying idea, not the implementation, but just the idea of building this like web first framework. That's ultimately what it was like the underlying selling point of Remix from the very beginning was to build a JavaScript framework that really looked like the web. It used web primitives under the hood, it used the Fetch API across the client and the server, it used board controllers, it used HTTP as a design basis across the board. So it really did lean into web first principles. And that spirit could still be there in something that they took and just sort of rethought from the ground up. What does the web have on the front end that we're not really utilizing to its fullest potential? Well, it has web components. Right. Again, no special knowledge here. I don't know if they're going to build Remix on top of web components, so they may or may not. But this is just me like pondering, like, what could the web provide you that remix v1 or v2 didn't provide you? And how can we build on this, like, underlying idea? And the new version of Remix could be whatever that is. And yet at a certain point they came out and said, you know what, we are going to really rethink everything from first principles. We are going to even rethink react, because while they obviously love react, they built on it, they stake their careers on it. You know, like REACT said, what is it, like 10, 11 years old at this point? 12 years old, you said 2013. So yeah, like 12, 13 years old. Something around there. It's been around the block for a while and it's still very valuable. But there's a lot of things we've learned since then that maybe there's something they could take forward. And again, no special knowledge. I don't actually know what it is they're going to build. But here's the thing I know about Michael and Ryan is they're always kind of like one or two steps ahead of where you and I are. And every time I've ever doubted them, they've proven me wrong. So we will see. I'm very excited to see what they build and I think they got the chops to build something really cool. So TBD on that.
B
Yeah, totally agree. And I think it's great that they're remixing it, to use the term, and rethinking from first principles because if you just settle, then that's what you're stuck with with. So I'm very excited about it. And I hadn't considered that it could be web components. And not that it is, you know.
C
But if it were, it really might not be. I don't know what their front end library of I do know it will be composition based because everything, like I said, that's like the underlying model that sold React in the first place was composition first. And so I know, I do know for a fact that they put high value on that and whatever we see will have a. A very composition driven API for building components. So I'm stoked to see what it is.
B
Same. Yeah, I'm looking forward to it. Always good to see new innovation in this. Now, getting back to Radix, I did want to ask about something that I actually don't know a lot about, even though I've used Radix a lot. When the topic of Radix comes up, inevitably ShadCN comes up. Can you explain the relationship between Radix and ShadCN and kind of how that came to be?
C
Yeah, so shadcn, for those who don't know, is kind of a design system builder or a component builder of sorts, where it is a component library that you typically would install from NPM in shadcn. Originally when it started, you would go to the website and it would have this giant list of components and you would click on like a tabs component or something in the docs and it would show you a bunch of code that you needed to copy and paste and drop in your app, which was slightly different approach, right? Like you didn't install anything from npm. There might be a few underlying dependencies, but it was a copy paste code approach, which was very old school in that way, which may have seemed counterintuitive, but for something like a component library, it was actually a really powerful idea that you should just own your component library. You should own the code. Because libraries come and go. They may or may not get neglected over the years. There may be limited capacity for you to customize certain things or add functionality, but if you own the code, it's way easier to make tweaks to the code. And for some reason people are terrified of going into the Node Modules folder. So that's not an option. You got to take it out of the node modules and stick it in your source directory and just own the code. And so that was a sort of novel concept in the REACT ecosystem at the time. And the ideas just sort of took off. And then over time it got a lot more sophisticated, they got a lot more components and then they ultimately built like a CLI tool that you could use to just drop the. So you didn't have to like manually copy paste things, you just dropped them into your project with a script and now they have A bunch of tools around like LLM usage that I'm not super familiar with. But the relationship that you're asking about is essentially that most of the components in shadcn are abstractions on top of Radix. Shadcn does provide a lot of other things for you. It also builds on Tailwind, so everything you download or copy from shadcn is going to be built on Tailwind classes. So it expects that you use Tailwind in your project. And yeah, like I said, it's built on top of Radix components as well. So if you go and look at like a shadcn dialog that's going to be under the hood. A Radix primitive dialogue that comes with a bunch of pre baked styles using Tailwind classes.
B
Okay, so could you think of it as like another theme? I guess I'm trying to.
C
It's a different approach to trying to solve a similar problem as Radix themes. Yeah, I mean certainly it Radix themes. The selling point is you want to be able to bootstrap something quickly. You go grab this thing, don't have to think about styles and then you can theme it. Right. Shedsian does provide a similar interface, except for again, it's not a library and the theming options are whatever you are presented with in Tailwind. And then from there you can sort of manipulate your Tailwind config and it will impact how every all of your chadsy and components ultimately look. But since you own the code, you can also go in and make more granular changes that you might not be able to with a, with a library first approach. So yeah, it is a different approach to solving a very similar problem.
B
Got it. Okay, and is there any like collaboration between the two teams on these two working together or like not at all.
C
But if anyone working on shadcn wants to come help us out, let us know. Been open to it. But yeah, waiting for that phone call still.
B
Okay, so this is making more sense as I've been kind of experimenting with vibe coding a little bit and making an app that is using shadcn. But then when I go look at my package JSON, it's all Radix and so it's because it's using the CLI to just put those components in from using ShadCN CLI. But they're Radix components and then it has their styles and their setup.
C
That's right. And it's not just Radix, there's other dependencies in the mix too. For certain components they come Baked with some, some icon libraries, I think. So yeah, there's a number of other libraries but essentially shadcn is building on top of other libraries to provide a slightly higher level of abstraction so that you can grab a component really quickly and get off to the races.
B
Very cool. So where do you see Radix going? Do you have big plans or big changes that you foresee coming or do you feel like it's fairly mature?
C
So I think for Radix primitives it's fairly mature. We have a wide adoption at this point and as we talked about, shadcn is built on top of it and it is working very well for a lot of people in production and there's not a lot more that we really need to build now that being said, there are additional primitives people have asked for and things that we are currently building. So there will be new primitives that pop up from time to time. But the overall suite of tools is pretty mature. And so Radix as a whole though again Radix is sort of a grouping of different things. It's not just one thing. Primitive is a piece of the puzzle, but there's a bigger puzzle at play. And when you start putting that together, I think the question gets very interesting. What is Radix? What does it become in the future? And the way that we've always thought about Radix is it is a toolkit for building on the web that's like very high level how we think about Radix. Everything else from my perspective is an implementation detail, the implementation of what do people need to reach for to build for the web. And I think there's still a lot of opportunity in answering that question. And it's something that we're actively discussing at work os. So I think we don't have like a very firm answer for that right away. Like I said, it's an active conversation and lots of really great ideas that we've been noodling on and we've got some experiments internal that we're working on to try and proof a concept, some of these ideas. So it's very much still baking. All I will say is that the work we're doing I think is pretty exciting and it'll be really cool when we finally get to roll something out to people to see what that might look like. But I think there's still a lot of exploration to do in answering that question. What are the tools people need to build for the web and how can we give you as provide as much value as we possibly can to fulfill that goal. So what that actually looks like tbd, but that's how I think of Radix evolving over the years. I mean, the web platform itself, like I said, has changed so much, but also how people build with LLMs and different AI tools, basically allowing you to drastically shortcut build times. And so like the interface for actually building things with LLMs is very different than how we've done things in the past. So I suspect we'll be leaning on that to some degree. But yeah, that's just kind of how I think about Radix and I think everything that we do moving forward will be in service of that bigger picture.
B
Very cool. You said that some new component or some new primitives might be coming. What goes into a decision to decide to add a new primitive to Radix?
C
Sure. Well, we build our entire design system at work OS on top of Radix. And so we see very intimately, like we have a very. Our culture is very big on dogfooding. So like pretty much any tools that we build for customers, we try and also use ourselves. And that's also true with Radix, like everything that you use as much as possible is built on top of Radix. And so that gives us a really useful insight as to what might be missing, what gaps there are that needed to be filled in Radix. And so we can see very quickly what Radix is good at and what gaps there might be. And like, how can we fill those gaps? Right, like, so we are, for example, we're an authentication company for the most part. Like work OS is a lot more than that, but a lot of our tools and services around authentication. And so, you know, as we're building components out for the work OS dashboard or the admin portal, we notice that, hey, we are reaching for other tools or we're hand rolling our own component for this thing. Right? One example being a one time password field. You know, we've all seen the one time password field, which is essentially six many inputs that all accept a single number. And then there are certain behaviors that are expected when you encounter one of these. Like one of them being if you paste into a single input, it actually pastes in all the inputs because it's, it's interesting because it's really one input. It's just visually six different inputs. But that also kind of comes with like when you visually alter an input. Maybe there's like different user expectations for how things behave than a normal input. So then you have to think about, okay, what happens if the user clicks on the fourth input and not the first one? You have to think about what happens if they, they focus that fourth input and then they try and paste a code. Do we start from the beginning or do we start from the middle? It's weird because in a single input you can't just put the cursor, you know, four places to the right. It's one input and there's only as much space as you've entered white space. So like there's different things you have to think about when. And this is what I talked about earlier. When you peel back the onion of something that seems very simple. It's actually, you have to think about a lot of different things. And so we looked at this and we said we don't have this in Radix. Why, like why don't we have this? It's pretty complex to implement. Well, it would provide a lot of value because tons of apps use this pattern. Let's just build one and put it in Radix. And so that's what we did. And so now it's still in sort of like an early pre release phase I think it is. The API is still in flux somewhat, so we've exported as an unstable prefix, but it is still documented. So you can go look at the Radix docs today and see our one time password field. And then we also recently rolled out another auth related component password toggle field. Another interesting one. This one was a fun one to build. Also it looks very simple on the surface. I will say it is a little simpler than the one time password, but it's still, I think, pretty useful. So you've got an input. Everyone's seen this pattern. It's for passwords. I may or may not want to be able to to mask the password. So you want a little toggle button to turn the password visibility on or off. And so it's fairly simple and straightforward, but you have to think about things like focus management, cursor position, when I want to toggle the password on and off because you don't want to have to keep tabbing back and forth. Right. Or if I click on the button, I might not want to move focus to the button because I'm still typing the password. Right. So little things like that you want to think about and we just hide all that logic away. So all you have to do is drop it into your code and customize it to fit your needs. And then we have a couple we haven't shipped that are also author Related. There's another one that I'm working on now that's a password strength indicator. So we've all seen that too, where you've got a list of different requirements that you need to fulfill and if your password is not at least eight characters or whatever it yells at you and as soon as you satisfy that need, it stops yelling at you. So we're building that out. And yeah, we have a couple ideas for new author related components and then there's, you know, there's some other non author related components as well. Just any sort of gaps we identify internally and also we get ideas from the community as well. And I know there's lots of components that people in the community have asked us for and we've been not building them for a while. So we hear you, but all I'll say is we've got some other stuff coming. So keep your eyes open.
B
Combo box, I imagine is one of those.
C
No, don't even say the word.
B
I thought that you had a really good explanation as to why that might not be. It's hard to do. Right.
C
That's the answer. You know, it's been brought up a number of times and at this point we kind of have. We joke about it a lot in our internal meetings but you know, like I said, keep your eyes open. Never know about that. Yeah.
B
And yeah, I just wanted to say on, you know, the auth specific components like particularly the OTP that field, like it is so critical to get that right. Like just as a user, if it's wrong and if I'm trying to like, if I mistype something and I have to like hit backspace and it's not going back to the previous one, like I'm just completely annoyed. And so that is something that is so important to get right. But also it's something that's super important to get right not just for humans, but for machines. And I'm thinking specifically like password managers being able to automatically fill that out and detect when that happens. Like now one password just kind of like fits it in and it goes. And if that doesn't work right away, like that's something that is real friction for real users all the time.
C
Absolutely. And it's not just one password. People use other password managers, they all have different mechanisms for handling this thing. And so yeah, we have to test that and make sure it works. And not only works with the password managers, but across different browsers and their password manager extensions has to work on mobile. Like another thing, if you're on. I'm sure Android has this too. I use an iPhone, so you know, it's probably everywhere. But you know, when I open up a page that has that one time password input, the second I get a text message, I get a little screen that says here's the code. And then you press that button and the code just auto fills and auto submits. We have to make sure that that works too. So, yeah, there's a handful of like little features that users expect and actually implementing them is a little bit more complicated than you might imagine.
B
Yeah, this is getting into the weeds a little bit. But I'm just curious, like, does it come down to it actually just being one field or is it like a specific name or specific attributes that might be on that text input?
C
Yeah, so different people have implemented this differently. The way we do it with Radix is it's actually implemented as six separate inputs. There are a few libraries. I've seen that what they do is they have a single input, but then they visually hide it and then mask it with these things that look like inputs. But then it. That sort of constrains you a bit because now like it has to. You can only focus one in like it's one input. So that input's the thing that always has the focus. Right. And when you enter one character and you move, you know, move over to the right and you have different characters, like when they visually look like inputs, you want to be able to see the focus on the currently active input or like what I perceive as the input. Right. So it's a very clever approach and I think there's actually a lot of merit to building it that way because it does remove a lot of complexity. But there's also some really weird nuances and edge cases that you have to consider. When something looks like something to a user, they expect it to behave a certain way. And trying to mask that behind another element that looks and behaves sort of differently to the user comes with a little bit of potential friction.
B
Yeah. There is one other question that I wanted to ask. Inevitably everything devolves in 2025 down to AI. And I'm curious how AI has affected Radix or has it? You mentioned it being popular with LLMs, for example. I think a big part of that's probably V0 and SHADCN building components out of that. But have you seen any other effects in this age of AI on how you build these components or how they're consumed or how you think about them?
C
Oh yeah, we think about this a lot. And I would say that the composition model in Radix, I think before we were Even thinking about AI, it turns out that LLMs really do naturally, like, work well with composition first APIs. And so it's really easy to ask a. An LLM something or go to ChatGPT and ask it for something to build you a REACT component. And a lot of times it's going to build you something that looks a lot like Radix because it's just the core composition model of React. And so I think just because we followed that pattern really closely, LLMs are already kind of like naturally good at building things out that either use Radix or look a lot like Radix, but in terms of how we can sort of build on that. Yeah, we have a lot of different ideas for that. You know, we want to make sure that you have like a Claude config file in your code base. That sort of helps the tooling understand Radix a little bit more in depth, understand how you've implemented it in your own code base. These are different things that we are probably going to add in the near future. They are things that we actively talk about, for sure. And then going back to like, my bigger picture question of, like, what is Radix at the end of the day, like a toolkit for building on the web? Okay. How do people build on the web? Increasingly it's going to be using AI, Right. That's only going to increase over time. So if that's how people build for the web, how does Radix fulfill that vision? Of course it's going to be AI to some degree. You know, what does that look like? Not exactly sure yet. But it's. It's something that we think about a lot. And again, a lot of ideas that we are currently baking. Yeah, I hate being vague about certain things, but I also don't want to say something and people get excited and then it doesn't happen and they're like, oh, you said this thing, and I don't know, we're just cooking.
B
Yeah, no, that's great. And I think that that's enough right now. We don't know where this is all going to go in a year from now. And so just knowing that it's on your radar as a maintainer and you're thinking, actively thinking about how people are going to interact with these tools and how people are going to build using this toolkit, I think that's comforting for sure. So, yeah, that's a great answer. Finally, is there anything that we haven't talked about that. You want people to know about Radix.
C
Oh yeah. So one thing we've been doing, my coworker and I, Michael Chan, have been doing a roughly weekly, bi weekly stream. We're still trying to figure out exact schedule, but we started streaming some just like, what do we do with Radix? Like, how do we work on it? It's very, very new, so we're still figuring out the format and all that, but it's been a lot of fun and I think it would be really useful for people to like just if you're really interested in stuff, seeing how the sausage is made and peeling back the onion or whatever other food analogy you want to make. But if you want to dig into the weeds of Radix with us, that's your opportunity, I think, to really do that. And also, even if you don't care about Radix, we talk a lot about like what goes into maintaining a popular open source library because I think that in of itself is very useful for people to have context. Like a lot of us just think of open source as this thing that you get for free and like there's not like a real person necessarily behind the screen actually delivering and working on this for you and giving you a lot of value for zero money. So I think it's really useful to just sort of like understand a little bit more about what goes into it and I don't know, maybe give you a little bit of empathy for the folks who are building it. I'm not like sobbing about the situation. We're doing fine, you know, But I do think it would be better for the community if everyone sort of like understood what goes into open source.
B
Yeah, absolutely. I love that level of transparency and just like thought process, you know, getting into the mindset a little bit is very eye opening. Not just for like from a maintainer's perspective or from, you know, a human perspective, but also just seeing like, like you said how that sausage is made or how the, you know, peeling back the onion, whatever it is very valuable just to your own learning and growth. Well, very cool. Chance, where can people find you on the Internet?
C
They can find me on bluesky is primarily where I spend the majority of my time though I am trying to spend less time on the Internet in general aside from the time that I work on it. But yeah, chance.dev which is my website and also my bluesky handle. So that's probably the best place you can find me if you want random thoughts on component libraries or food or whatever thought pops into my dumb brain.
B
Awesome. Well, thank you so much for spending time with us today. And we'll catch you next time.
C
Yeah, thanks, Nick. This is awesome.
Episode date: November 18, 2025
Guest: Chance Strickland (Software Engineer at WorkOS & Radix UI Maintainer)
Host: Nick Nisi
This episode dives deep into Radix UI—a collection of headless React component primitives prioritizing accessibility, composability, and usability—through insights from maintainer Chance Strickland. The discussion covers the history and philosophy of Radix, its component architecture, relationships to projects like ShadCN UI, evolving web primitives, future plans, and how new technologies and trends (including AI and LLMs) are changing the component library landscape.
[00:00–05:19]
What is Radix?
On Pronunciation:
"I've always said Radix, but I hear people all the time will come up and say, hey, I love Radix UI. ... The project was started by a team of half Americans and half Brits." – Chance Strickland [02:22]
[05:19–08:10]
Headless Components & Flexibility:
"We want to give you maximum flexibility in terms of the presentation of the components, but the underlying patterns should behave similarly across the board... the look and feel is obviously going to be determined in large part by your brand." – Chance Strickland [06:15]
Themes & Extensibility:
[08:30–11:16]
Icons and Color System:
"Things like line weight and face sizing and how each icon scales up to different screen sizes... All of that matters a lot more than people realize." – Chance Strickland [08:47]
[12:17–15:23]
Styling Approach:
"If you are using something like Tailwind already... may not be the best fit to then go and grab Radix Themes. ...But we have other levels of abstraction and you can go grab Radix Primitives and then you can slap whatever Tailwind classes you want on any element you want." – Chance Strickland [14:06]
[15:54–19:42]
Web Standards Catching Up:
Dialog, Select, Collapsible) predate or improve upon native HTML elements."If [web primitives] can do everything that Radix can do today... maybe we could either phase out the component altogether and recommend people use web primitives, or we could build our primitives on top of the web..." – Chance Strickland [18:14]
[19:42–30:32]
Background and Early Inspirations:
Maintaining Reach UI:
"The first component that I remember building that way was an accordion... I built it the way that I would imagine Ryan Florence would have built it into Reach." – Chance Strickland [22:36]
Reflections on the Ecosystem & Remix:
"What does the web have on the front end that we're not really utilizing... Well, it has web components. Right. ...No special knowledge here, but this is just me pondering..." – Chance Strickland [32:55]
[37:11–41:37]
What is ShadCN?
"You should just own your component library... it's way easier to make tweaks to the code." [37:34]
"Most of the components in shadcn are abstractions on top of Radix... If you go and look at like a shadcn dialog that's going to be under the hood a Radix primitive dialog that comes with a bunch of pre baked styles using Tailwind classes." – Chance Strickland [37:34]
[41:37–44:13]
Maturity and Plans:
"What is Radix? What does it become in the future? ...It's a toolkit for building on the web, that's very high level how we think about Radix." – Chance Strickland [41:49]
[44:13–50:15]
Dogfooding at WorkOS:
"This is what I talked about earlier. When you peel back the onion of something that seems very simple, it's actually... a lot more complicated than you might imagine." – Chance Strickland [50:15]
[51:33–53:58]
LLM and Composability:
"An LLM... or ChatGPT... It's really easy to ask it to build you a React component. And a lot of times it's going to build you something that looks a lot like Radix, because it's just the core composition model of React." – Chance Strickland [52:03]
On building primitives:
"Everything that we do presents as fairly simple. But then once you peel back the onion a little bit, there's a reason people don't want to do it themselves. It's actually very hard, a lot harder, a lot more time consuming than people really need to be investing." – Chance Strickland [10:18]
On headless component tradeoffs:
"You want tools that help you spend time on your product and not waste time thinking about color scales. And that’s really what it comes down to." – Chance Strickland [10:56]
On the impact of AI:
"How do people build on the web? Increasingly it’s going to be using AI... So if that’s how people build for the web, how does Radix fulfill that vision? Of course it’s going to be AI to some degree." – Chance Strickland [53:25]
| Topic/Section | Timestamp | |:-----------------------------------------------|:----------| | Introduction & Guest Background | 00:00–02:15 | | What is Radix UI? Umbrella projects | 03:07–05:19 | | Headless primitives and accessibility | 05:19–08:10 | | Design: themes, colors, icons | 08:30–11:16 | | Working with themes, Tailwind, and CSS | 12:17–15:23 | | Web primitives & browser APIs vs. Radix | 15:54–19:42 | | Chance’s path to open source/Radix | 19:42–26:03 | | Reach UI, composition, and innovation | 26:03–30:32 | | Thoughts on Remix, React Router, and evolution | 30:32–37:11 | | Relationship between Radix and ShadCN UI | 37:11–41:37 | | Future plans for Radix | 41:37–44:13 | | Building new primitives (OTP, auth, etc.) | 44:13–50:15 | | AI, LLMs, and component libraries | 51:33–53:58 | | Open source maintenance, streaming, community | 54:25–55:40 | | Chance on where to connect online | 56:03–56:28 |
[54:25–56:28]
Chance and Michael Chan run a recurring stream walking through Radix maintenance and open source contribution—offering transparency and insight to the process.
Encourages empathy and understanding for maintainers in open source.
"If you want to dig into the weeds of Radix with us, that's your opportunity... Also, even if you don't care about Radix, we talk a lot about what goes into maintaining a popular open source library." – Chance Strickland [54:25]
Chance can be found primarily on Bluesky (chance.dev).
Radix UI stands out by balancing the power of composable, accessible React primitives with a philosophy of user-owned, style-agnostic components. It plays a foundational role in the modern React ecosystem—powering high-level solutions like ShadCN UI, responding to new web standards, and adapting to AI-driven development trends. This episode not only explores how and why Radix works but provides practical context (and relatable stories) for anyone curious about building robust, accessible UIs—and the evolving world of open source.
This summary preserves the thoughtful, conversational style of the episode, giving newcomers an engaging snapshot of Radix UI—and the people and ideas shaping it.