Customization
Last updated on 2026-04-05
The Finance Dashboard Kit is designed to be customized for your personal finance app, banking dashboard, or accounting tool. All components use design tokens and Tailwind CSS utilities, making brand adaptation straightforward.
Changing Colors
Update CSS custom properties in app/globals.css. The default Mint Ledger theme uses oklch hue 170. Change the hue to rebrand the entire kit:
:root {
/* Change from teal (hue 170) to blue (hue 240) */
--primary: oklch(0.45 0.2 240);
--primary-foreground: oklch(0.98 0 0);
--accent: oklch(0.94 0.02 240);
--accent-foreground: oklch(0.35 0.15 240);
--ring: oklch(0.55 0.18 240);
}
.dark {
--primary: oklch(0.7 0.18 240);
--primary-foreground: oklch(0.15 0.02 240);
}
All 9 screens automatically inherit the new colors -- buttons, badges, stat cards, charts, sidebar, progress bars, and focus rings all update at once.
Modifying Built-in Themes
The kit ships with 6 themes defined in globals.css. You can modify existing themes or add new ones:
/* Add a custom "Ocean" theme */
.theme-ocean {
--background: oklch(0.99 0.002 210);
--foreground: oklch(0.17 0.02 210);
--primary: oklch(0.45 0.2 210);
--primary-foreground: oklch(0.98 0.005 210);
/* ... remaining tokens with hue 210 */
}
.dark .theme-ocean,
.theme-ocean.dark,
.theme-ocean:is(.dark *) {
--background: oklch(0.16 0.02 210);
--foreground: oklch(0.96 0.005 210);
--primary: oklch(0.7 0.18 210);
/* ... */
}
Then add the theme to the ColorTheme type in types/index.ts and the ThemeSwitcher component.
Changing Typography
Configure fonts in app/layout.tsx:
import { Inter, DM_Sans, JetBrains_Mono } from "next/font/google";
const inter = Inter({ subsets: ["latin"], variable: "--font-inter" });
const dmSans = DM_Sans({ subsets: ["latin"], variable: "--font-dm-sans" });
const jetbrainsMono = JetBrains_Mono({ subsets: ["latin"], variable: "--font-jetbrains" });
Swap these for any Google Font or local font files. The CSS variables --font-sans, --font-heading, and --font-mono control body text, headings, and code respectively.
Replacing Seed Data
All mock data lives in data/seed.ts. Replace it with your data source:
API calls
import { getTransactions } from "@/lib/api"
export default async function TransactionsPage() {
const transactions = await getTransactions()
return <TransactionTable transactions={transactions} />
}
Database (Prisma, Drizzle)
import { db } from "@/lib/db"
const transactions = await db.transaction.findMany({
orderBy: { date: "desc" },
include: { category: true, account: true },
})
Banking API (Plaid)
// app/api/plaid/transactions/route.ts
export async function GET() {
const response = await plaidClient.transactionsSync({
access_token: process.env.PLAID_ACCESS_TOKEN!,
})
return Response.json(response.data.added)
}
Supabase
import { createClient } from "@supabase/supabase-js"
const supabase = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
)
const { data: transactions } = await supabase
.from("transactions")
.select("*, category:categories(*), account:accounts(*)")
.order("date", { ascending: false })
Customizing the Sidebar
Edit components/layout/app-sidebar.tsx to add or remove navigation items:
const navLinks = [
{ href: "/", label: "Dashboard", icon: LayoutDashboard },
{ href: "/transactions", label: "Transactions", icon: ArrowLeftRight },
{ href: "/budgets", label: "Budgets", icon: PieChart },
{ href: "/accounts", label: "Accounts", icon: Landmark },
{ href: "/bills", label: "Bills & Subscriptions", icon: Receipt },
{ href: "/goals", label: "Goals", icon: Target },
{ href: "/reports", label: "Reports", icon: BarChart3 },
{ href: "/settings", label: "Settings", icon: Settings },
// Add your custom pages here
{ href: "/investments", label: "Investments", icon: TrendingUp },
]
Adding New Pages
- Create a new route in
app/(dashboard)/your-page/page.tsx - The page automatically inherits the dashboard layout (sidebar, header, command palette, FAB)
- Add a sidebar link in
components/layout/app-sidebar.tsx
// app/(dashboard)/investments/page.tsx
export default function InvestmentsPage() {
return (
<div className="space-y-6">
<h1 className="font-heading text-2xl font-bold">Investments</h1>
{/* Your investment tracking content */}
</div>
)
}
Adding New Chart Types
The kit uses Recharts 3. Add new chart components in components/dashboard/ or create a new domain directory:
// components/dashboard/investment-growth-chart.tsx
"use client"
import { AreaChart, Area, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from "recharts"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
interface InvestmentGrowthChartProps {
data: { date: string; value: number }[]
}
export function InvestmentGrowthChart({ data }: InvestmentGrowthChartProps) {
return (
<Card>
<CardHeader>
<CardTitle>Investment Growth</CardTitle>
</CardHeader>
<CardContent>
<ResponsiveContainer width="100%" height={300}>
<AreaChart data={data}>
<CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey="date" />
<YAxis />
<Tooltip />
<Area
type="monotone"
dataKey="value"
stroke="var(--chart-1)"
fill="var(--chart-1)"
fillOpacity={0.1}
/>
</AreaChart>
</ResponsiveContainer>
</CardContent>
</Card>
)
}
Customizing Dashboard Widgets
Add new widgets to the dashboard by:
- Create the widget component in
components/dashboard/ - Add a widget ID to the
WidgetConfigarray in the layout store - Add the widget to the dashboard page with a visibility check
// In the dashboard page
{visible.has("investment-growth") && (
<InvestmentGrowthChart data={investmentData} />
)}
Modifying the Layout Store
The Zustand store in lib/stores/use-layout-store.ts manages widget visibility and layout presets. Customize presets for your use case:
const presets = {
full: allWidgetIds,
minimalist: ["net-worth", "income", "expenses", "income-expense-chart"],
business: ["cash-flow", "income-expense-chart", "top-merchants", "pl-report"],
personal: ["savings-rate", "budget-progress", "goals", "bills-due"],
// Add your custom preset
investor: ["net-worth", "asset-allocation", "investment-growth", "net-worth-chart"],
}
Responsive Breakpoints
The kit uses Tailwind's responsive prefixes throughout:
| Breakpoint | Width | Typical Usage |
|---|---|---|
sm |
640px | 2-column stat cards, horizontal filter layout |
md |
768px | Sidebar becomes visible, 2-column chart grid |
lg |
1024px | 3-column stat cards, wider chart containers |
xl |
1280px | Maximum content width utilization |
Removing Unused Features
Delete directories you don't need:
- Don't need budgets? Delete
app/(dashboard)/budgets/andcomponents/budgets/ - Don't need goals? Delete
app/(dashboard)/goals/andcomponents/goals/ - Don't need bills? Delete
app/(dashboard)/bills/andcomponents/bills/ - Don't need reports? Delete
app/(dashboard)/reports/andcomponents/reports/ - Update the sidebar navigation in
components/layout/app-sidebar.tsx - Run
pnpm buildto verify no broken imports
Using shadcn/ui CLI
Add new components alongside the kit:
npx shadcn@latest add <component-name>
Components install to components/ui/ and integrate seamlessly with the existing design tokens. The kit uses shadcn/ui v4 with @base-ui/react.