# Pricing

> A three-tier pricing grid with a highlighted popular plan, feature checklists, and per-plan calls to action.

A shadcn/ui block from the [@quill](https://www.quilldesignsystem.com) registry, listed on [shadcn.exchange](https://shadcn.exchange/r/quill/pricing).

- Page, with a live preview: https://shadcn.exchange/r/quill/pricing
- Screenshot: https://abzjhwgwpdpz7ua5.public.blob.vercel-storage.com/shots/quill/pricing-light-f62193c124a3f1de.png
- Registry item: https://www.quilldesignsystem.com/r/pricing.json
- Categories: marketing, commerce
- Listed: 2026-10-13, source last changed 2026-10-13

## Install

```bash
npx shadcn@latest add https://www.quilldesignsystem.com/r/pricing.json
```

Run it in a project that has shadcn/ui set up. It adds the files below and installs what they depend on.

## Dependencies

- Registry items: `card`, `button`, `badge`, `https://www.quilldesignsystem.com/r/icon.json`

## Notes from the registry

A three-tier pricing grid with a highlighted popular plan, feature checklists, and per-plan calls to action. Do: Mark exactly one plan as featured (ring + Popular badge) to guide the decision. Don't: Feature more than one plan, or none — either dilutes the recommendation this pattern exists to make. Use feature-section when you're describing capabilities in general, not comparing specific paid tiers against each other. Use order-summary when the user has already chosen a plan and is now reviewing a specific purchase, not comparing options.

## Files

### `registry/blocks/pricing.tsx`

```tsx
import {
  Card,
  CardHeader,
  CardTitle,
  CardDescription,
  CardContent,
  CardFooter,
} from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'
import { Icon } from '@/components/ui/icon'

const plans = [
  { name: 'Starter', price: '$0', blurb: 'For trying things out.', features: ['1 project', 'Community support', '1 GB storage'], cta: 'Get started', featured: false },
  { name: 'Pro', price: '$18', blurb: 'For growing teams.', features: ['Unlimited projects', 'Priority support', '100 GB storage', 'Analytics'], cta: 'Start free trial', featured: true },
  { name: 'Enterprise', price: 'Custom', blurb: 'For large organizations.', features: ['SSO & SAML', 'Dedicated support', 'Unlimited storage', 'Audit logs'], cta: 'Contact sales', featured: false },
]

/** A three-tier pricing grid with a highlighted popular plan, feature checklists, and per-plan calls to action. */
export function Pricing() {
  return (
    <div className="grid grid-cols-1 gap-6 md:grid-cols-3">
      {plans.map((p) => (
        <Card key={p.name} className={p.featured ? 'ring-2 ring-ring' : undefined}>
          <CardHeader>
            <div className="flex items-center justify-between">
              <CardTitle>{p.name}</CardTitle>
              {p.featured && <Badge>Popular</Badge>}
            </div>
            <CardDescription>{p.blurb}</CardDescription>
            <div className="pt-2">
              <span className="text-3xl font-medium text-foreground tabular-nums">{p.price}</span>
              {p.price !== 'Custom' && <span className="text-sm text-muted-foreground">/mo</span>}
            </div>
          </CardHeader>
          <CardContent className="flex flex-col gap-2">
            {p.features.map((f) => (
              <div key={f} className="flex items-center gap-2 text-sm text-foreground">
                <Icon name="check" size={16} className="text-primary" />
                {f}
              </div>
            ))}
          </CardContent>
          <CardFooter className="mt-auto">
            <Button variant={p.featured ? 'default' : 'outline'} className="w-full">
              {p.cta}
            </Button>
          </CardFooter>
        </Card>
      ))}
    </div>
  )
}
```
