Plan comparison
Compare meaningful differences between plans and billing periods.
Preview
Plan comparison preview
Live · keyboard ready
Room for the way you work
Only the details that change between plans. Switch billing to see what you would pay.
Billed month to month
Compare plans
8 of 8 featuresWhat changes
Team
For smaller teams$13per seat / month
Studio
For work across teams$27per seat / month
Active projects
TeamUnlimited
StudioUnlimited
Shared workspaces
Team1 workspace
StudioUnlimited
Guest reviewers
Team5 per project
StudioUnlimited
Version history
Team30 days
StudioUnlimited
Approval flows
TeamNot included
StudioIncluded
Custom roles
TeamNot included
StudioIncluded
Source exports
TeamIncluded
StudioIncluded
Support
TeamEmail
StudioPriority email
When to use
- Comparing two tiers side by side with a feature matrix.
- Pricing pages that switch between monthly and yearly prices.
- Long feature lists where people want to see only the differences.
When not to use
- Use usage-pricing when price depends on seats or volume.
- Use segmented-control alone for a simple billing toggle.
- Use cancel-flow for downgrade or cancellation decisions.
shadcn CLI
Also installs (4)
- manicat-foundation
- button
- segmented-control
- switch
Manual install(+)
registry.jsonjson
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "plan-comparison",
"type": "registry:block",
"title": "Plan comparison",
"description": "Compare meaningful differences between plans and billing periods.",
"categories": [
"blocks"
],
"dependencies": [
"@radix-ui/react-switch",
"lucide-react",
"motion"
],
"registryDependencies": [
"https://manicat.viraza.net/r/manicat-foundation.json",
"https://manicat.viraza.net/r/button.json",
"https://manicat.viraza.net/r/segmented-control.json",
"https://manicat.viraza.net/r/switch.json"
],
"files": [
{
"path": "registry/blocks/plan-comparison/plan-comparison.tsx",
"type": "registry:component",
"target": "@components/manicat/blocks/plan-comparison/plan-comparison.tsx"
},
{
"path": "registry/blocks/plan-comparison/plan-comparison.module.css",
"type": "registry:component",
"target": "@components/manicat/blocks/plan-comparison/plan-comparison.module.css"
},
{
"path": "registry/components/switch/switch.tsx",
"type": "registry:component",
"target": "@components/manicat/switch/switch.tsx"
},
{
"path": "registry/components/switch/switch.module.css",
"type": "registry:component",
"target": "@components/manicat/switch/switch.module.css"
},
{
"path": "registry/components/segmented-control/segmented-control.tsx",
"type": "registry:component",
"target": "@components/manicat/segmented-control/segmented-control.tsx"
},
{
"path": "registry/components/segmented-control/segmented-control.module.css",
"type": "registry:component",
"target": "@components/manicat/segmented-control/segmented-control.module.css"
},
{
"path": "registry/components/button/button.tsx",
"type": "registry:component",
"target": "@components/manicat/button/button.tsx"
},
{
"path": "registry/components/button/button.module.css",
"type": "registry:component",
"target": "@components/manicat/button/button.module.css"
}
],
"docs": "Docs and live preview: https://uiarc.dev/components/blocks/plan-comparison",
"meta": {
"tier": "free",
"kind": "block",
"docs": "https://manicat.viraza.net/components/blocks/plan-comparison",
"markdown": "https://uiarc.dev/components/blocks/plan-comparison/markdown"
}
}Usage
Install the component, then copy this into your app. Change the content and the props to fit your screen.
example.tsxtsx
"use client";
import { PlanComparison } from "manicat/registry/blocks/plan-comparison/plan-comparison";
export function PlanComparisonExample() {
return <PlanComparison />;
}
Examples
Real screens rather than isolated props. Switch to Code to copy a whole example into your project.
Pricing page Drop the plan comparison on a pricing route as is.
Pricing page
Drop the plan comparison on a pricing route as is. preview
Live · keyboard ready
Room for the way you work
Only the details that change between plans. Switch billing to see what you would pay.
Billed month to month
Compare plans
8 of 8 featuresWhat changes
Team
For smaller teams$13per seat / month
Studio
For work across teams$27per seat / month
Active projects
TeamUnlimited
StudioUnlimited
Shared workspaces
Team1 workspace
StudioUnlimited
Guest reviewers
Team5 per project
StudioUnlimited
Version history
Team30 days
StudioUnlimited
Approval flows
TeamNot included
StudioIncluded
Custom roles
TeamNot included
StudioIncluded
Source exports
TeamIncluded
StudioIncluded
Support
TeamEmail
StudioPriority email
pricing-page-drop-the-plan-comparison-on-a-pricing-route-as-is-.tsxtsx
"use client";
import { PlanComparison } from "manicat/registry/blocks/plan-comparison/plan-comparison";
export function PlanComparisonPricingExample() {
return <PlanComparison />;
}
Accessibility
- The matrix uses table, row, columnheader, rowheader, and cell roles.
- Prices are aria-live with aria-atomic so the full value is read.
- The chosen plan is announced in a role="status" footer.
Motion
- Prices count between billing periods and the selection highlight moves with layoutId.
- Extra feature rows expand in height with a light blur.
- Reduced motion jumps to the final values and disables height animation.
Responsive behavior
- Below 640px the feature header column hides and each feature name spans the row above its two values.
- Below 365px plan and value padding tighten so both plans still fit side by side.
Performance
- Prices tween with a single animate call per value; the selection highlight uses one layoutId.
- Showing extra rows animates height, so keep the matrix to a few dozen features.
Notes for AI
- Use when people compare two tiers side by side.
- Edit the pricing and features constants; there is no selection callback, so wire the Button onClick yourself.
- Composes Arc Button, SegmentedControl, and Switch.