Pricing Comparison

A feature-by-feature pricing matrix: rows are features, columns are plans, and each cell is a check, a minus or a value. Group rows into sections, highlight the recommended plan, and hang a tooltip off any row.

Compare plans
Starter
$0/mo
ProPopular
$29/mo
Enterprise
Custom
Projects & team
Projects5UnlimitedUnlimited
Team members3UnlimitedUnlimited
Storage1 GB100 GB1 TB
Support & security
Community supportIncludedIncludedIncluded
Priority supportNot includedIncludedIncluded
SSO & SAMLNot includedNot includedIncluded
Dedicated managerNot includedNot includedIncluded

Installation#

# One-time setup (tokens + lib helpers)npx koalaui-cli@latest init# Add this component (its dependencies come along)npx koalaui-cli@latest add pricing-comparison

Usage#

import {  PricingComparison,  PricingComparisonHeader,  PricingComparisonPlan,  PricingComparisonSection,  PricingComparisonRow,  PricingComparisonCell,} from "@/components/ui/pricing-comparison"import { Button } from "@/components/ui/button"// `featured` is the 0-based index of the highlighted plan column.<PricingComparison featured={1}>  <PricingComparisonHeader label="Compare plans">    <PricingComparisonPlan name="Starter" price="$0" period="/mo">      <Button variant="outline" size="sm">Get started</Button>    </PricingComparisonPlan>    <PricingComparisonPlan name="Pro" price="$29" period="/mo" badge={<Badge variant="orange" dot pill size="sm">Popular</Badge>}>      <Button size="sm">Start free trial</Button>    </PricingComparisonPlan>  </PricingComparisonHeader>  <PricingComparisonSection title="Projects & team">    <PricingComparisonRow label="Projects">      <PricingComparisonCell>5</PricingComparisonCell>      <PricingComparisonCell>Unlimited</PricingComparisonCell>    </PricingComparisonRow>    <PricingComparisonRow label="Priority support" hint="One-hour response on business days.">      <PricingComparisonCell included={false} />      <PricingComparisonCell included />    </PricingComparisonRow>  </PricingComparisonSection></PricingComparison>

Cell states#

A PricingComparisonCell is one of three things. Pass a value as children for a literal like 100 GB or Unlimited (rendered tabular-nums so columns align). With no children it draws a success check, or a muted minus when included={false}. Every glyph cell also carries an SR-only "Included" / "Not included" label.

Feature
Monthly
$29/mo
Annual
$23/mo
BilledMonthlyYearly
Effective price$348/yr$276/yr
Cancel anytimeIncludedIncluded
Price lockNot includedIncluded

Centered headers and marks#

align="center" on the root puts every plan header on its column's axis, the same one as the checks and values under it, so a matrix without CTAs (a versus table, a plan overview) reads as labelled columns. It is set once on the root, so the columns can never disagree. The default, start, keeps the name and price on a left edge over full-width buttons. icon on a plan adds a mark above its name: a plan glyph here, a product logo in a versus matrix like the one in Migrating from shadcn/ui. It is decorative; the name stays the column's label.

Feature
Starter
$0/mo
Pro
$29/mo
Enterprise
Custom
Projects5UnlimitedUnlimited
Priority supportNot includedIncludedIncluded
SSO & SAMLNot includedNot includedIncluded

Row hints#

Add a hint to any PricingComparisonRow to append an info glyph beside the feature name. It reveals the detail in a tooltip on hover or focus, so terse row labels stay scannable while the caveats and limits stay one hover away. Set hintLabel to name the trigger for assistive tech (defaults to "More information").

<PricingComparisonRow label="Storage" hint="Pooled across the whole team, not per seat.">  <PricingComparisonCell>1 GB</PricingComparisonCell>  <PricingComparisonCell>100 GB</PricingComparisonCell>  <PricingComparisonCell>1 TB</PricingComparisonCell></PricingComparisonRow>

API reference#

PricingComparison

The matrix root (a scrollable <table>). featured is the 0-based index of the plan column to highlight (the single source of truth: the header cap and the body column tint both derive from it). Omit it for no highlight. align places every plan header in its column: start (the default) or center.

PricingComparisonHeader · PricingComparisonPlan

The sticky plan-header row and its column cells. Header takes an optional label for the empty top-left corner. Each Plan takes name, icon (a decorative mark above the name), price, period, and an optional badge; its children are the CTA, stretched full-width and pinned to the bottom so buttons line up across columns.

PricingComparisonSection

A labelled group of rows (a <tbody>). The title renders as a full-width band above its rows. Omit the title for an ungrouped block.

PricingComparisonRow · PricingComparisonCell

A feature row and its per-plan cells. Row takes a label (the leading row header) and an optional hint / hintLabel for an info tooltip. Each Cell renders its children as a value, or a check / muted minus by included when empty. Order the cells to match the plan columns.

Reach for Pricing (the card table) for the marketing moment: a handful of plans, each selling itself with a short feature list and a CTA. Reach for Pricing Comparison when buyers are deciding between plans and need to compare line by line: it lays every feature out as a row so differences are obvious at a glance. Many sites use both, the cards up top and the full matrix below.