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

  1. Create a new route in app/(dashboard)/your-page/page.tsx
  2. The page automatically inherits the dashboard layout (sidebar, header, command palette, FAB)
  3. 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:

  1. Create the widget component in components/dashboard/
  2. Add a widget ID to the WidgetConfig array in the layout store
  3. 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/ and components/budgets/
  • Don't need goals? Delete app/(dashboard)/goals/ and components/goals/
  • Don't need bills? Delete app/(dashboard)/bills/ and components/bills/
  • Don't need reports? Delete app/(dashboard)/reports/ and components/reports/
  • Update the sidebar navigation in components/layout/app-sidebar.tsx
  • Run pnpm build to 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.