{
    "id": "bhaskar/offline-expense-tracker-pwa",
    "kind": "plan",
    "title": "Offline Expense Tracker (installable app)",
    "summary": "Track spending by category and month, set budgets and export CSV. Installs like an app and works with no internet.",
    "author": "Admin",
    "stars": 0,
    "url": "https://ownlyplans.com/bhaskar/offline-expense-tracker-pwa/",
    "stack": [
        "Dexie.js",
        "PWA",
        "React",
        "Tailwind",
        "TypeScript",
        "Vite"
    ],
    "tools": [
        "cursor",
        "claude-code",
        "lovable"
    ],
    "difficulty": "beginner",
    "license": "cc-by-4.0",
    "version": "1.0",
    "overview": "A private expense tracker that lives on the phone: no server, no sign-up, nothing to pay for hosting. Data is stored in the browser (IndexedDB) and the app installs to the home screen and works offline.\n\nGreat first AI build: small, useful every day, and easy to deploy for free.\n\nBefore you start: Node.js 20+ and Cursor, Claude Code or Lovable. About 1 hour.",
    "steps": [
        {
            "title": "Create the app",
            "body": "In a terminal:\n\nnpm create vite@latest expense-tracker -- --template react-ts\ncd expense-tracker\nnpm install\nnpm install dexie dexie-react-hooks\n\nSave AGENTS.md in the project root.",
            "prompt": "Read AGENTS.md. Add Tailwind CSS to this Vite + React project following the current official Tailwind guide for Vite, and replace the starter page with an empty app shell: header \"Expenses\", a main area and a bottom nav with Add, History, Budgets.",
            "done": "npm run dev shows the shell with Tailwind styles.",
            "files": [
                "AGENTS.md"
            ]
        },
        {
            "title": "Add the database",
            "body": "All data lives in IndexedDB through Dexie. Amounts are integers (paise/cents) to avoid rounding errors.",
            "prompt": "Create src/db.ts exactly as in the attached db.ts. Add helpers in src/money.ts: toMinor(\"125.50\") → 12550 and formatMoney(12550) → \"₹125.50\" using Intl.NumberFormat with the browser locale (currency INR by default, easy to change in one constant).",
            "done": "The app builds and an \"ExpenseTracker\" database appears in DevTools → Application → IndexedDB.",
            "files": [
                "db.ts",
                "Dexie.js"
            ]
        },
        {
            "title": "Add expenses fast",
            "body": "The add screen must take under 5 seconds: amount, category chips, optional note, date defaulting to today.",
            "prompt": "Build the Add screen: large amount input (numeric keyboard on phones), category chips (Food, Transport, Bills, Shopping, Health, Other; remember the last used), optional note, date (default today). Save to db.expenses and show a small \"Saved\" toast. Validate: amount > 0.",
            "done": "You can add an expense on a phone-sized screen in a few taps.",
            "files": []
        },
        {
            "title": "History by month",
            "body": "A list grouped by month with totals, and edit/delete.",
            "prompt": "Build History: month picker (default current month), total for the month, totals per category as simple horizontal bars (CSS only, no chart library), and the list of expenses (newest first) with edit and delete (confirm before delete). Use useLiveQuery so the screen updates instantly.",
            "done": "Adding or deleting an expense updates totals immediately.",
            "files": [
                "db.ts"
            ]
        },
        {
            "title": "Monthly budgets",
            "body": "Set a monthly budget per category and see how much is left.",
            "prompt": "Build Budgets: a monthly amount per category (db.budgets). On History show spent / budget per category with a bar that turns amber at 80% and red over 100%.",
            "done": "Going over a budget shows a red bar.",
            "files": []
        },
        {
            "title": "Backup: CSV export and import",
            "body": "Data is on the device only, so give people a backup.",
            "prompt": "Add Settings with: Export CSV (date, amount with 2 decimals, category, note; proper quoting) and Import CSV (validate every row, skip duplicates by date+amount+category+note, show \"Imported N, skipped M\"). Also a \"Delete all data\" button with a typed confirmation.",
            "done": "Export, delete all, import: your data comes back.",
            "files": []
        },
        {
            "title": "Make it installable and offline",
            "body": "Install the plugin: npm install -D vite-plugin-pwa. You need two icons (192×192 and 512×512 PNG) in /public.",
            "prompt": "Configure vite-plugin-pwa in vite.config.ts: registerType \"autoUpdate\", a manifest (name \"Expense Tracker\", short_name \"Expenses\", display \"standalone\", theme and background colours, icons pwa-192x192.png and pwa-512x512.png). Show a small \"Update available\" prompt when a new version is ready. Then explain how to test offline in Chrome DevTools.",
            "done": "After npm run build && npm run preview, the browser offers \"Install\", and the app opens with the network turned off.",
            "files": [
                "vite-plugin-pwa"
            ]
        },
        {
            "title": "Deploy for free",
            "body": "Any static host works: Netlify, Vercel, Cloudflare Pages or GitHub Pages.",
            "prompt": "Prepare this app for deployment as a static site: check the production build, add a short README with how to run, build and deploy to Netlify or Vercel, and list what to test on a real phone (install, offline, add, export).",
            "done": "The app is live on a public URL and installs on your phone.",
            "files": []
        }
    ],
    "files": [
        {
            "type": "markdown",
            "name": "AGENTS.md",
            "note": "Project rules. Works with Cursor, Claude Code (rename to CLAUDE.md) and Lovable (paste as knowledge).",
            "file": "agents",
            "url": "https://ownlyplans.com/bhaskar/offline-expense-tracker-pwa/agents/"
        },
        {
            "type": "markdown",
            "name": "db.ts",
            "note": "The whole database layer. Save as src/db.ts.",
            "file": "db",
            "url": "https://ownlyplans.com/bhaskar/offline-expense-tracker-pwa/db/"
        },
        {
            "type": "git",
            "name": "Dexie.js",
            "note": "IndexedDB wrapper used for storage.",
            "url": "https://github.com/dexie/Dexie.js"
        },
        {
            "type": "git",
            "name": "vite-plugin-pwa",
            "note": "Adds install + offline support.",
            "url": "https://github.com/vite-pwa/vite-plugin-pwa"
        }
    ],
    "install": "",
    "how_to_use": "Call get_step with step 1, do it, check \"done when\", then continue."
}