# Introduction
billui is an open collection of billing components for React, built on top of shadcn/ui and distributed via the shadcn registry. The goal is simple: **help you ship billing UI faster**.
This is my small contribution to the open source community that taught me so much. {'<3'}
## Not a library—an open component distribution
Like shadcn/ui, billui is not a typical install-from-NPM library. It's an open collection you can copy, modify, and customize directly in your codebase. You own the code. No wrappers, no overrides, no fighting with the library.
Billing UI is deceptively complex. Pricing tables, plan groups, invoice history—each one has edge cases and design decisions that take time to get right. billui gives you battle-tested starting points so you can focus on what makes your product unique.
## Why billui?
* **Open source & copy-first**: Direct access to source so you can adapt components to your design system
* **Ship faster**: Stop rebuilding the same billing components from scratch
* **shadcn compatible**: Install via the shadcn CLI, works with your existing setup
* **Composable**: Build complex billing UIs from simple, reusable primitives
* **Accessible**: Built with semantic HTML and accessibility in mind
* **Type-safe**: Full TypeScript support with exported types
# Animated Usage Card
import {
AnimatedUsageCard,
AnimatedUsageCardHeader,
AnimatedUsageCardPeriod,
AnimatedUsageCardAction,
AnimatedUsageCardSummary,
AnimatedUsageCardLabels,
AnimatedUsageCardLabel,
AnimatedUsageCardProgress,
AnimatedUsageCardList,
AnimatedUsageCardItem,
AnimatedUsageCardItemLabel,
AnimatedUsageCardItemValue,
AnimatedUsageCardMeter,
AnimatedUsageCardTotal,
} from "@/registry/animated";
Buy CreditsImage Generation120 creditsVideo Generation85 creditsUpscaling (4x)62 creditsBackground Removal45 creditsStyle Transfer35 credits
`}
>
## Installation
```bash
npx shadcn@latest add "https://billui.com/r/animated-usage-card.json"
```
```tsx title="components/ui/animated-usage-card.tsx"
"use client";
import { cva, type VariantProps } from "class-variance-authority";
import { ChevronDown } from "lucide-react";
import { motion, useMotionValue, useSpring, useTransform } from "motion/react";
import * as React from "react";
import { cn } from "@/lib/utils";
import { Button } from "@/components/ui/button";
// ... component code
```
## Examples
### Basic Usage
Simple usage card with animated progress bar and itemized list.
API CallsStorage
`}
>
API Calls
Storage
### With Animated Meters
Use `AnimatedUsageCardMeter` to show individual resource usage with animated progress bars and number interpolation.
Manage
`}
>
Manage
### Collapsible List
Enable `collapsible` on `AnimatedUsageCardList` to show a preview with bouncy expand/collapse animation.
Build MinutesEdge InvocationsFunction CallsBandwidth
`}
>
Build Minutes
Edge Invocations
Function Calls
Bandwidth
### With Animated Total
The `AnimatedUsageCardTotal` row animates in with a bounce effect and the amount value interpolates smoothly.
Pro PlanExtra Seats (3)Storage Add-on
`}
>
Pro Plan
Extra Seats (3)
Storage Add-on
### Elevated Variant
Use `variant="elevated"` to add a shadow for more visual prominence.
Upgrade
`}
>
Upgrade
## API Reference
### AnimatedUsageCard
The root container component with entrance animation.
| Prop | Type | Default |
| --------- | ------------------------- | ----------- |
| `variant` | `"default" \| "elevated"` | `"default"` |
### AnimatedUsageCardPeriod
Displays the billing period or days remaining.
| Prop | Type | Default |
| --------------- | -------- | ------- |
| `daysRemaining` | `number` | — |
### AnimatedUsageCardAction
Action button in the header. Extends shadcn Button props.
| Prop | Type | Default |
| --------- | ----------------------------------- | ----------- |
| `variant` | `"default" \| "outline" \| "ghost"` | `"outline"` |
### AnimatedUsageCardLabel
Displays a labeled amount with optional limit.
| Prop | Type | Default |
| ---------- | ------------------- | -------- |
| `label` | `string` | — |
| `amount` | `number` | — |
| `limit` | `number` | — |
| `currency` | `string` | `"$"` |
| `align` | `"left" \| "right"` | `"left"` |
### AnimatedUsageCardProgress
Animated progress bar showing usage against a limit with spring physics.
| Prop | Type | Default |
| ------------- | --------- | ------- |
| `value` | `number` | — |
| `max` | `number` | `100` |
| `showOverage` | `boolean` | `false` |
### AnimatedUsageCardList
Container for usage items with optional bouncy expand/collapse animation.
| Prop | Type | Default |
| ----------------- | --------- | ------- |
| `collapsible` | `boolean` | `false` |
| `defaultExpanded` | `boolean` | `false` |
| `visibleItems` | `number` | `1.5` |
| `dividers` | `boolean` | `true` |
### AnimatedUsageCardItem
Individual usage line item.
| Prop | Type | Default |
| ------------- | --------- | ------- |
| `highlighted` | `boolean` | `false` |
### AnimatedUsageCardItemValue
Value display for a usage item.
| Prop | Type | Default |
| ---------- | -------- | ------- |
| `amount` | `number` | — |
| `currency` | `string` | `"$"` |
| `unit` | `string` | — |
### AnimatedUsageCardMeter
Visual meter showing resource usage with animated progress and number interpolation.
| Prop | Type | Default |
| ---------------- | --------- | ------- |
| `used` | `number` | — |
| `limit` | `number` | — |
| `label` | `string` | — |
| `unit` | `string` | — |
| `showPercentage` | `boolean` | `false` |
### AnimatedUsageCardTotal
Animated total row with entrance animation and number interpolation.
| Prop | Type | Default |
| ---------- | -------- | --------- |
| `label` | `string` | `"Total"` |
| `amount` | `number` | — |
| `currency` | `string` | `"$"` |
### useAnimatedUsageCardList
Hook to access the list expansion state from child components.
```tsx
const {
expanded,
setExpanded,
itemCount,
collapsedHeight,
expandedHeight
} = useAnimatedUsageCardList();
```
## Comparison with UsageCard
This component is API-compatible with the non-animated `UsageCard`. You can swap between them by changing the import:
```tsx
// Without animations
import { UsageCard, UsageCardList, ... } from "@/components/ui/usage-card"
// With animations
import { AnimatedUsageCard, AnimatedUsageCardList, ... } from "@/components/ui/animated-usage-card"
```
The only API difference is:
* `AnimatedUsageCardList` uses `visibleItems` (number of items) instead of `collapsedHeight` (pixels)
# Billing Address
import { Label } from "@/components/ui/label";
import {
BillingAddress,
BillingAddressInput,
BillingAddressCountry,
BillingAddressState,
} from "@/registry/ui";
`}
>
## Installation
```bash
npx shadcn@latest add "https://billui.com/r/billing-address.json"
```
```tsx title="components/ui/billing-address.tsx"
"use client";
import * as React from "react";
import { Input } from "@/components/ui/input";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { cn } from "@/lib/utils";
import { COUNTRIES, getStatesForCountry, type IState } from "./billing-address-data";
// ... component code
```
## Examples
### Minimal Form
A compact version with only essential fields.
`}
>
### With Server Actions
The `name` prop enables native form submission—works with `useActionState` and Server Actions.
```tsx title="billing-form.tsx"
"use client";
import { useActionState } from "react";
function BillingForm() {
const [state, formAction] = useActionState(updateBilling, null);
return (
);
}
```
### Controlled State
For real-time validation or conditional UI.
```tsx
function ControlledBillingForm() {
const [country, setCountry] = useState("US");
const [state, setState] = useState("");
const showTaxMessage = state === "CA";
return (
{showTaxMessage &&
## Installation
```bash
npx shadcn@latest add "https://billui.com/r/card-input.json"
```
```tsx title="components/ui/card-input.tsx"
"use client";
import * as React from "react";
import { cn } from "@/lib/utils";
import { CardBrandIcons, type CardBrand } from "./card-icons";
// ... component code
```
## Examples
### Basic Grouped Inputs
Use `CardInputGroup` to combine all card inputs into a single grouped component with shared focus states.
`}
>
### Individual Inputs
Use each input component separately for custom layouts with individual labels and styling.
***
Can't find what you need? Check our [GitHub repository](https://github.com/commet-labs/billui) and open an issue to request a new component.
# Invoice Card
import {
InvoiceCard,
InvoiceCardIcon,
InvoiceCardContent,
InvoiceCardHeader,
InvoiceCardNumber,
InvoiceCardStatus,
InvoiceCardDate,
InvoiceCardAmount,
InvoiceCardActions,
InvoiceCardAction,
} from "@/registry/ui";
INV-2024-001INV-2024-002INV-2024-003
`}
>
),
);
PlanCardFeature.displayName = "PlanCardFeature";
interface PlanCardActionProps
extends React.ComponentPropsWithoutRef {}
const PlanCardAction = React.forwardRef(
({ className, ...props }, ref) => (
),
);
PlanCardAction.displayName = "PlanCardAction";
export {
PlanCard,
PlanCardHeader,
PlanCardBadge,
PlanCardTitle,
PlanCardDescription,
PlanCardPrice,
PlanCardFeatures,
PlanCardFeature,
PlanCardAction,
planCardVariants,
};
export type {
PlanCardProps,
PlanCardBadgeProps,
PlanCardPriceProps,
PlanCardFeatureProps,
PlanCardActionProps,
};
```
## Examples
### Default Variant
BasicFor individuals5 projectsBasic analyticsPriority supportGet Started
`}
>
Basic
For individuals
5 projects
Basic analytics
Priority support
Get Started
### Highlighted Variant
Use the `highlighted` variant to emphasize a recommended plan.
Most PopularProFor growing teamsUnlimited projectsAdvanced analyticsPriority supportGet Started
`}
>
Most Popular
Pro
For growing teams
Unlimited projects
Advanced analytics
Priority support
Get Started
### With Discount
Show original price with strikethrough to highlight discounts.
40% OFFProFor growing teamsUnlimited projectsAdvanced analyticsPriority supportGet Started
`}
>
40% OFF
Pro
For growing teams
Unlimited projects
Advanced analytics
Priority support
Get Started
### Yearly Period
Save 20%YearlyBilled annuallyAll features2 months freeSubscribe
`}
>
Save 20%
Yearly
Billed annually
All features
2 months free
Subscribe
### One-time Payment
Use `period="once"` for lifetime or one-time purchases.
LifetimeOne-time paymentAll features foreverFree updatesBuy Now
`}
>
Lifetime
One-time payment
All features forever
Free updates
Buy Now
### Compact Variant
Use the `compact` variant for smaller plan cards.
StarterGet started quickly3 projectsCommunity supportStart Free
`}
>
Starter
Get started quickly
3 projects
Community support
Start Free
### Large Size
Use `size="lg"` for more spacious plan cards.
Best ValueProfessionalEverything you need to scale your businessUnlimited everythingAdvanced analyticsPriority supportCustom integrationsAPI accessStart Free Trial
`}
>
Best Value
Professional
Everything you need to scale your business
Unlimited everything
Advanced analytics
Priority support
Custom integrations
API access
Start Free Trial
## API Reference
### PlanCard
The root container component.
| Prop | Type | Default |
| --------- | ----------------------------------------- | ----------- |
| `variant` | `"default" \| "highlighted" \| "compact"` | `"default"` |
| `size` | `"default" \| "lg"` | `"default"` |
### PlanCardBadge
Optional badge for highlighting plans.
| Prop | Type | Default |
| --------- | --------------------------------------- | ----------- |
| `variant` | `"default" \| "secondary" \| "outline"` | `"default"` |
### PlanCardPrice
Displays the price with optional original price for discounts.
| Prop | Type | Default |
| ---------------- | ----------------------------- | --------- |
| `amount` | `number` | — |
| `currency` | `string` | `"$"` |
| `period` | `"month" \| "year" \| "once"` | `"month"` |
| `originalAmount` | `number` | — |
### PlanCardFeature
Individual feature item with included/excluded state.
| Prop | Type | Default |
| ---------- | --------- | ------- |
| `included` | `boolean` | `true` |
### PlanCardAction
CTA button for the plan card.
| Prop | Type | Default |
| --------- | --------------------------------------- | ----------- |
| `variant` | `"default" \| "outline" \| "secondary"` | `"default"` |
# Plan Group
import {
PlanGroup,
PlanGroupHeader,
PlanGroupTitle,
PlanGroupDescription,
PlanGroupToggle,
PlanGroupContent,
PlanPrice,
PlanCard,
PlanCardHeader,
PlanCardBadge,
PlanCardTitle,
PlanCardDescription,
PlanCardPrice,
PlanCardFeatures,
PlanCardFeature,
PlanCardAction,
} from "@/registry/ui";
Simple, transparent pricing
Choose the plan that works best for you. All plans include a 14-day free trial.
FreeFor individualsUp to 3 projectsBasic analyticsCommunity supportCustom integrationsPriority supportGet Started
ProMost Popular
For growing teamsUnlimited projectsAdvanced analyticsPriority supportCustom integrationsDedicated managerGet Started
`}
>
Simple, transparent pricing
Choose the plan that works best for you. All plans include a 14-day free trial.
Free
For individuals
Up to 3 projects
Basic analytics
Community support
Custom integrations
Priority support
Get Started
Pro
Most Popular
For growing teams
Unlimited projects
Advanced analytics
Priority support
Custom integrations
Dedicated manager
Get Started
## Installation
```bash
npx shadcn@latest add "https://billui.com/r/plan-group.json"
```
```tsx title="components/ui/plan-group.tsx"
"use client";
import { cva, type VariantProps } from "class-variance-authority";
import * as React from "react";
import { cn } from "@/lib/utils";
import { PlanCardPrice } from "./plan-card";
// ... component code
```
## Examples
### Horizontal Card Layout
Use `layout="horizontal"` on `PlanCard` combined with `layout="vertical"` on `PlanGroupContent` to create a row-style pricing list.
Compare plans
## Installation
```bash
npx shadcn@latest add "https://billui.com/r/usage-card.json"
```
```tsx title="components/ui/usage-card.tsx"
"use client";
import { cva, type VariantProps } from "class-variance-authority";
import { ChevronDown, ChevronUp } from "lucide-react";
import * as React from "react";
import { cn } from "@/lib/utils";
import { Button } from "@/components/ui/button";
import { Progress } from "@/components/ui/progress";
// ... component code
```
## Examples
### Basic Usage
Simple usage card with progress bar and itemized list.
API CallsStorage
`}
>
API Calls
Storage
### Elevated Variant
Use `variant="elevated"` to add a shadow for more visual prominence.
Upgrade
`}
>
Upgrade
### With Usage Meters
Use `UsageCardMeter` to show individual resource usage with visual progress bars.
Manage
`}
>
Manage
### Collapsible List
Enable `collapsible` on `UsageCardList` to show a preview with expand/collapse functionality.
Build MinutesEdge InvocationsFunction CallsBandwidth
`}
>
Build Minutes
Edge Invocations
Function Calls
Bandwidth
### With Highlighted Items
Use `highlighted` prop on items to create zebra striping.
ComputeStorageBandwidthFunctions
`}
>
Compute
Storage
Bandwidth
Functions
### With Total Row
Add a `UsageCardTotal` at the bottom to show the sum of all charges.
Pro PlanExtra Seats (3)Storage Add-on
`}
>
Pro Plan
Extra Seats (3)
Storage Add-on
### Overage Warning
The progress bar turns red when usage exceeds the limit.
Billing cycle exceededAdd Credits
`}
>
Billing cycle exceeded
Add Credits
### Custom Currency
Display amounts in different currencies.
AlmacenamientoTransferencia
`}
>
Almacenamiento
Transferencia
### Custom Period Text
Pass custom children to `UsageCardPeriod` for custom text.
Jan 1 - Jan 31, 2024View History
`}
>