Radix Is Dead, Use This Instead... (Base UI)

BBetter Stack
컴퓨터/소프트웨어AI/미래기술

Transcript

00:00:00stop using radix components and move on what to well base ui in fact if you're a shazian fan
00:00:06there's already the choice to switch over now if you haven't heard of base ui before it's actually
00:00:10from the original creators of radix floating ui and material ui and it's a headless ui library
00:00:15so it brings the functionality and accessibility of components but you still bring the design
00:00:20which is particularly important these days as llms still aren't great considering all of those edge
00:00:24cases and accessibility needs but what i've described there is also exactly what radix is
00:00:30so why do you need a new one well let's just jump right in and let me show you the key differences
00:00:35i'll start really quickly by showing you the base ui documentation so you can see all of the
00:00:44components we have on the left here you can see they have pretty much all of the ones that you
00:00:48would need in your component library and even some advanced ones like the combo box that we have here
00:00:52which you can't get in radix and you'll see for all of these that have a nice example on how you
00:00:57can do this and style it with something like css modules you can even change this to a tailwind
00:01:01example if you want as well and the documentation is really good but we're not here to compare the
00:01:06documentation so let's just jump right into the first key difference and the one that you'll
00:01:10probably hear the most and that is just that base ui is actively maintained and radix is kind of in
00:01:15a zombie state i mean if we take a look at that github contribution charts you'll see that base ui
00:01:20is growing and growing and radix seems to apply an occasional commit here and there but it's even more
00:01:25clear when we take a look at the prs and issues that have been closed in the last month you can
00:01:29see base ui has closed 58 issues and merged 154 pull requests and radix has closed none and merged
00:01:36no prs the tldr of what happened to radix was that workos actually bought the company behind radix
00:01:42and just didn't really invest in radix so the radix team largely left and we're in the state that we're
00:01:47in now radix's co-creator even said that he'd only use radix if it was his last option and yes he is
00:01:53now working on base ui so it's really just about making sure your apps and dependencies are actively
00:01:58maintained and won't cause you a headache in the future if you hit a bug that isn't going to be
00:02:02fixed and even better base ui is actually made to be quite similar to radix so migration shouldn't be
00:02:08too bad but that also doesn't mean they can't sneak in a few improvements and one of my favorite
00:02:13improvements is how they've handled the as child prop that you get in radix now if you haven't seen
00:02:17this before what i've got here is actually a radix select and if i wanted to render a custom component
00:02:22here as my select trigger if i simply wrapped it with the select trigger component you can see that
00:02:27i get a wrapper component and then also the button that says subscribe something you should click by
00:02:31the way but if i actually wanted to make it so the subscribe button was serving as the select trigger
00:02:36all i need to do in radix is simply add on the as child prop to the trigger and that is telling
00:02:41radix to merge all of the props and functionality of this select trigger with the component that we
00:02:46have set as its child you can see that's happening based on the fact this class name here is being
00:02:50merged with the button and it's actually overwriting it in this case so if i simply delete that prop and
00:02:55save you can see we now have a button but this is serving functionally as my select trigger now
00:03:00that's a pretty handy functionality to have but a common complaint with it was that it wasn't very
00:03:04explicit and i'll admit that sometimes when i was quickly looking over code i would sometimes miss
00:03:09this prop and therefore i'd miss the cause of the issue so if we switch over to seeing how this is
00:03:13done in base ui you can still get the exact same functionality so i have a button over here that's
00:03:18serving as my select trigger but if you take a look at the code instead of using as child base ui uses
00:03:24the render prop now on the render prop you then specify the component that you want to well render
00:03:29in as your select trigger so this is a very minor change but i just think it makes it way more
00:03:34explicit exactly what this is doing it's literally rendering in this component so you don't have to
00:03:39look whether it's using the child component and look for that as child prop it's just as i said
00:03:43a small change but a very good one in my opinion and that's not even the full power of the render
00:03:48prop we can see here when i'm building out a switch we can actually pass through a function to the
00:03:52render prop so we're able to access the props on the state of the component that we're actually
00:03:56building out so in this case the switch thumb one what this allows us to do is a choose what component
00:04:01we actually want to apply the pass through props onto and then we can also do some custom rendering
00:04:05logic or some custom styling logic based on the state of the component so in this case with the
00:04:10switch thumb we can choose where there's checked dirty disabled filled and loads more so in this
00:04:14case we're simply doing a check for whether it is actually checked or not and in that case we're
00:04:18rendering in a different icon there's even a hook that actually allows you to build in that render
00:04:22prop into your own custom components but we're getting a little bit advanced here but hopefully
00:04:27you can see anything custom you want to do you should be able to handle it with base ui now if
00:04:31we jump back to my select component the next difference is that base ui allows some of your
00:04:35components to be data driven and we can see that in the case of the select here what i have currently
00:04:40is the radix select code so we have an array here where we have our label and value and to actually
00:04:44get the values into the select down here the only thing we need to do is map over the apple's array
00:04:49and then simply render in a select item in radix and that will add in these values like so if we
00:04:54then jump over to how this is done in base ui you can see it's incredibly similar we still have my
00:04:59array up here of the actual label and values and down here we're still mapping over it and rendering
00:05:03in a select item but we're also including it in another place which is on this select route here
00:05:08we're including that array and this actually has a very subtle impact that means the component is now
00:05:13aware of the data that it's going to render before rendering and that means that there's slightly
00:05:17better performance especially when it comes to server side rendering one thing i do think could
00:05:22actually be improved about this though is at the moment i'm passing through apples as my items prop
00:05:26but then down here i'm also mapping over the apples array as well so we're using it in two places what
00:05:32i think they should do instead is what react aria does which is another headless library here you can
00:05:36see we have our animals array we're actually passing this through as the items here and then for the
00:05:41children of that all we're doing is using a function and this is going to know all of the items that've
00:05:45been passed through on the parent element so we're not using that array in two places and the parent
00:05:50element is serving as the data provider so it's definitely something i still think could be improved
00:05:55a little bit but if we head back to my select component i want to show you another difference
00:05:59but this one is actually specific to the select component as the render prop and also the data
00:06:03driven approach you'll see across pretty much all of the components but this one is specific to select
00:06:08that is that you can have a multi-select this is something that was painfully missing in radix
00:06:13you can see here in base ui all you need to do is add on the prop to the select route saying multiple
00:06:17it can be true or false and then your select simply becomes a multi-select and it is that easy and to
00:06:22take it a step further base ui even has some other components that we're missing in radix like a combo
00:06:27box and auto complete as it really is the benefit of being actively maintained so they can respond
00:06:33to user requests now there's two more differences that i want to show you from radix and base ui
00:06:38and we'll switch over to using the checkbox component because i'm a little bit bored of
00:06:41that select component and the first difference that i want to show you is around styling base ui
00:06:45actually gives you another styling choice that i think is really cool we can see here at the moment
00:06:50i'm currently using tailwind you can use all of the traditional approaches like normal css css
00:06:55modules and loads more but if you are using something like tailwind one of the ways you
00:06:59typically style a component like this is by using data attributes for the state so we have data
00:07:04checked here and if it is checked we're going to use background primary you can see we just have a
00:07:08very long string for styling this in tailwind which can sometimes become a little bit of a problem so
00:07:13one of the options that base ui gives you that can help with this is you can actually use a function
00:07:17as your class name this gives you access to the state of the component so in the case of the check
00:07:22box here i'm applying styles based on whether the state is checked or disabled you can see i'm doing
00:07:26that with a simple conditional here and i sometimes think this is just a nicer way for a quick glance
00:07:31when you're looking over your code to see where exactly those checked and disabled styles are
00:07:35coming from instead of having to scan that single line and look for those data attributes i think
00:07:40it's especially even more helpful if you're using something like vanilla css it also works really
00:07:45well with another library that i really like called tailwind variants you can see here i'm simply
00:07:49passing through the state to my checkbox function and up in my tailwind variant checkbox we have our
00:07:53base styles but then we also have our variants and you can see here i'm simply saying if checked is
00:07:58true apply these styles if disabled is true apply these ones and i just think sometimes this is way
00:08:02clearer than using those data attributes but it's definitely up to your opinion and what you're
00:08:06comfortable with using it's just super nice that base ui gives us all of these choices i'll also
00:08:11add that using a function as a class name was something i first fell in love with from react
00:08:14area so it really seems to me like we have react area over here which does have a steeper learning
00:08:19curve and radix which is quite simple and base ui has sort of met in the middle and taken the
00:08:23features that i like about both of them and created me the ultimate headless library now that's all of
00:08:28the key differences that i wanted to go over in this video but there is still loads more like base ui has
00:08:33great support for react hook form and tan stack form it has animation support to make it a nice
00:08:38and easy process to actually animate your components and it even has features like input scrubbing
00:08:42nested dialogues and triggering menus on hover and i'm sure if you have a reasonable request they'd
00:08:47actually respond to it over on the github as it is actively maintained it is also worth saying though
00:08:52that i probably wouldn't jump to migrating my radix app over to base ui straight away as i don't think
00:08:57radix is completely broken if i'm starting a new project i definitely use base ui now and if i wanted
00:09:02a feature like a combo box or an autocomplete i'd also consider migrating my application let me know
00:09:07what you think of base ui in the comments though while you're down there subscribe and as always
00:09:11see you in the next one

Key Takeaway

Base UI is positioned as the modern successor to Radix, offering active maintenance, superior component variety, and more explicit developer patterns for building accessible React applications.

Highlights

Base UI is a headless library from the creators of Radix

Timeline

Introduction to Base UI and the State of Radix

The speaker introduces Base UI as the new go-to headless UI library for React developers, particularly those who previously used Radix or Shadcn. Developed by the original creators of industry standards like Material UI, it focuses on providing core functionality and accessibility while leaving the design to the developer. The video notes that while Radix provided similar benefits, the industry is shifting toward Base UI due to evolving needs. The documentation is highlighted for its high quality and support for various styling methods like CSS Modules and Tailwind. This section sets the stage for a detailed comparison between the old standard and the new contender.

Maintenance Disparity and the 'Zombie State' of Radix

A critical look at the GitHub activity reveals a stark contrast between Base UI and Radix, with Radix showing almost no recent contributions. The speaker explains that after WorkOS acquired the team behind Radix, investment stalled and key creators moved on to work on Base UI. Statistical evidence is provided, showing Base UI merging over 150 pull requests while Radix merged none in the same period. This lack of maintenance makes Radix a risky choice for future-proofing applications against bugs. Choosing Base UI ensures that developers are using a library that will actually receive updates and security fixes.

Improving the Developer Experience: Render Props vs. asChild

The speaker dives into technical improvements, specifically focusing on how Base UI handles component composition compared to Radix's 'asChild' prop. While Radix used 'asChild' to merge functionality into children, Base UI adopts a more explicit 'render' prop pattern. This section demonstrates how the render prop can take a function to access the internal state of a component, such as whether a switch is checked. This allows for conditional rendering of icons or styles directly within the component structure. Such a pattern is presented as being more readable and less prone to being overlooked during code reviews.

Data-Driven Components and Server-Side Rendering

Base UI introduces a data-driven approach for complex components like Select, where items are passed as a prop to the root element. This allows the component to be aware of its data before the rendering phase, leading to performance gains in server-side rendering (SSR) scenarios. The speaker compares this favorably to Radix, where mapping usually occurs exclusively in the children. However, a slight critique is offered regarding the redundancy of passing data both to the root and mapping it manually. The speaker suggests that Base UI could further improve by following patterns seen in React Aria. This section emphasizes the technical maturity and efficiency of the Base UI architecture.

New Components and Advanced Styling Choices

The video highlights the inclusion of highly requested components that Radix lacked, such as the Multi-select, Combo Box, and Autocomplete. Beyond new components, Base UI offers a unique styling choice: the ability to use a function as a class name. This feature allows developers to pass the component's state, like 'disabled' or 'checked,' directly into styling utilities like Tailwind Variants. This method is contrasted with the traditional data-attribute approach, which can lead to long, hard-to-read strings in Tailwind. The speaker concludes that Base UI successfully bridges the gap between the simplicity of Radix and the power of React Aria.

Final Recommendations and Advanced Features

The final section covers additional features including native support for React Hook Form, TanStack Form, and built-in animation support. Advanced UI patterns like input scrubbing and nested dialogues are also mentioned as part of the library's robust feature set. The speaker provides a pragmatic recommendation: while existing Radix projects don't need an immediate, urgent migration, all new projects should start with Base UI. The video ends with a call to action for developers to explore the library's active GitHub community for future requests. This summary reinforces the message that Base UI is currently the most viable path forward for React UI development.

Community Posts

View all posts