Staaarter

Billing Plan Comparison Minimal

A stripped-down plan comparison table that shows only the rows that actually differ between tiers, instead of a long feature checklist. Each row renders a check, a dash, or a plain text value per plan, and one plan can be visually highlighted as the recommended choice. Built for pricing pages and upgrade screens where a shorter, denser table helps someone decide faster than a full feature matrix would.

By Staaarter Team
Billing
Updated June 18, 2026
Docs
Live preview

Docs

Installation

A real shadcn registry command, not a copy-paste stand-in: it fetches this block plus its badge, button dependencies and any missing npm packages, and installs them straight into your project.

npx shadcn add https://staaarter.com/r/billing-plan-comparison-minimal.json

Prefer not to use the CLI? Copy the source from the Code toggle above into src/components/blocks/billing/billing94.tsx instead.

Usage

The file also exports billing94Demo, the exact props behind the preview above. Spread it to get a working section in one line, then replace it with your own data.

import { Billing94, billing94Demo } from "@/components/blocks/billing/billing94";

export default function Page() {
  return <Billing94 {...billing94Demo} />;
}

Props

PropTypeDefaultDescription
headingstringnoneOptional heading above the table.
descriptionstringnoneOptional supporting text under the heading.
plansMinimalComparisonPlan[]nonePlans rendered as columns, in the order given.
rowsMinimalComparisonRow[]noneComparison rows. Each row's values array is matched to plans by index.
classNamestringnoneExtra classes for the outer wrapper.

Types

interface MinimalComparisonPlan {
  id: string;
  name: string;
  price: string;
  priceSuffix?: string;
  ctaLabel?: string;
  ctaHref?: string;
  highlighted?: boolean;
  badge?: string;
}

interface MinimalComparisonRow {
  label: string;
  /** One value per plan, matched by index to the plans array. true/false render as check/dash icons, a string renders as text. */
  values: (boolean | string)[];
}

Behavior notes

  • Each row's values array is matched to the plans array by index, not by plan id, so both arrays need to stay in the same order.
  • A value of true renders a primary-colored check icon, false renders a faint dash, and a string renders as plain text, so the same row type covers boolean features and numeric limits like seat counts.
  • Setting highlighted on a plan gives that whole column a tinted background and switches its button to the solid variant, without needing a separate "featured" prop.
  • The grid column count is derived from plans.length, so the table works with two or more plans without hardcoded column classes.
  • Missing a value for a plan on a given row (a shorter values array than plans) falls back to rendering a dash rather than crashing.

Frequently asked questions