Base UI
shadcn/ui
Shadcnblocks

Shadcn Blocks + Base UI

Shadcnblocks now supports Base UI and Radix UI. Same beautiful blocks, your choice of underlying primitives.

Choose Your Primitive Library

Both Radix UI and Base UI provide accessible, unstyled primitives. Choose the one that fits your project best.

Radix UI

The established choice

  • Battle-tested in production
  • Extensive component library
  • Large community ecosystem
style: "radix-vega"

Base UI

The lightweight alternative

  • Active development
  • Modern API
  • New and advanced components
style: "base-vega"
Radix UI
← Drag to compare →
Base UI
components/ui/tooltip.tsx
"use client"
import * as React from "react"
import { Tooltip as TooltipPrimitive } from "radix-ui"
import { cn } from "@/lib/utils"
function TooltipProvider({
delayDuration = 0,
...props
}: React.ComponentProps<typeof TooltipPrimitive.Provider>) {
return (
<TooltipPrimitive.Provider
data-slot="tooltip-provider"
delayDuration={delayDuration}
{...props}
/>
)
}
function Tooltip({
...props
}: React.ComponentProps<typeof TooltipPrimitive.Root>) {
return <TooltipPrimitive.Root data-slot="tooltip" {...props} />
}
function TooltipTrigger({
...props
}: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {
return <TooltipPrimitive.Trigger data-slot="tooltip-trigger" {...props} />
}
function TooltipContent({
className,
sideOffset = 0,
children,
...props
}: React.ComponentProps<typeof TooltipPrimitive.Content>) {
return (
<TooltipPrimitive.Portal>
<TooltipPrimitive.Content
data-slot="tooltip-content"
sideOffset={sideOffset}
className={cn(
"data-open:animate-in data-open:fade-in-0...",
className
)}
{...props}
>
{children}
<TooltipPrimitive.Arrow className="..." />
</TooltipPrimitive.Content>
</TooltipPrimitive.Portal>
)
}
export { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger }
components/ui/tooltip.tsx
"use client"
import { Tooltip as TooltipPrimitive } from "@base-ui/react/tooltip"
import { cn } from "@/lib/utils"
function TooltipProvider({
delay = 0,
...props
}: TooltipPrimitive.Provider.Props) {
return (
<TooltipPrimitive.Provider
data-slot="tooltip-provider"
delay={delay}
{...props}
/>
)
}
function Tooltip({ ...props }: TooltipPrimitive.Root.Props) {
return <TooltipPrimitive.Root data-slot="tooltip" {...props} />
}
function TooltipTrigger({ ...props }: TooltipPrimitive.Trigger.Props) {
return <TooltipPrimitive.Trigger data-slot="tooltip-trigger" {...props} />
}
function TooltipContent({
className,
side = "top",
sideOffset = 4,
align = "center",
alignOffset = 0,
children,
...props
}: TooltipPrimitive.Popup.Props &
Pick<
TooltipPrimitive.Positioner.Props,
"align" | "alignOffset" | "side" | "sideOffset"
>) {
return (
<TooltipPrimitive.Portal>
<TooltipPrimitive.Positioner
align={align}
alignOffset={alignOffset}
side={side}
sideOffset={sideOffset}
className="isolate z-50"
>
<TooltipPrimitive.Popup
data-slot="tooltip-content"
className={cn(
"data-open:animate-in data-open:fade-in-0...",
className
)}
{...props}
>
{children}
<TooltipPrimitive.Arrow className="..." />
</TooltipPrimitive.Popup>
</TooltipPrimitive.Positioner>
</TooltipPrimitive.Portal>
)
}
export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }
Key difference: radix-ui vs @base-ui/react/tooltip
Same styling, different primitives

Simple Configuration

One setting in your components.json controls both the UI library and visual style.

components.json
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "base-maia",
"rsc": true,
"tsx": true,
"tailwind": {
"config": "",
"css": "app/globals.css",
"baseColor": "neutral",
"cssVariables": true
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui"
}
}
Style
{library}-{style}
Examples
radix-vega, radix-nova, radix-maia
base-vega, base-nova, base-maia

Ready to Try Base UI?

Head to the Explorer, select Base UI, and see your blocks with the new primitives.