Comparison Table

Plan comparison grid with a monthly/yearly switch that rolls every price, plan columns in a sticky header over scrolling feature rows, collapsible feature groups, check / dash / partial / text cells, a recommended column tinted top to bottom, and a plan switcher with one cross-fading column in narrow containers — the detailed companion to PricingTable.

Preview

Comparison Table preview width

Install

Add it with the shadcn CLI, or copy the source manually.

$ bunx --bun shadcn add @karaui/comparison-table
@karaui not found? Add it to components.json
{
  "registries": {
    "@karaui": "https://karaui.kamisama-v0.my.id/r/{name}.json"
  }
}

@karaui is in shadcn's public registry directory, so the latest CLI needs no setup. On an older CLI, merge this into the existing file once and every @karaui/… install resolves.

API Reference

plans
ComparisonPlan[]
—
groups
ComparisonGroup[]
—
billing?
"monthly" | "yearly"
—
defaultBilling?
"monthly" | "yearly"
monthly
onBillingChange?
((billing: ComparisonBilling) => void)
—
defaultOpenGroups?
string[]

Groups open initially. Default: all.

—
mobilePlan?
string

Plan shown in the narrow (single-column) layout.

—
defaultMobilePlan?
string
—
onMobilePlanChange?
((planId: string) => void)
—
onSelect?
((plan: ComparisonPlan, billing: ComparisonBilling) => void)
—
currency?
string

ISO 4217 code. Default "USD".

USD
locale?
string

Default "en-US" so server and client agree.

en-US
yearlyBadge?
ReactNode

Badge beside "Yearly". Default "−20%"; null hides it.

−20%
recommendedLabel?
ReactNode

Label on the recommended column. Default "Recommended".

Recommended
bodyClassName?
string

Classes for the scrolling body (set a max height here). Default `max-h-[22rem]`.

—
className?
string
—

Keep in mind

Some components on this site are inspired by or recreated from existing work across the web. I'm not here to take credit; just to learn, experiment, and sometimes push things a bit further. If something looks familiar and I forgot to mention you, reach out and I'll fix that right away.

Updated