Back to skills
SkillHub ClubShip Full StackFull Stack

expense-tracker

Track daily expenses in structured markdown files organized by month. Use when the user wants to log spending, view expense summaries, analyze spending patterns, or manage personal finance tracking. Supports categories, tags, and monthly summaries.

Packaged view

This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.

Stars
3,084
Hot score
99
Updated
March 20, 2026
Overall rating
C4.5
Composite score
4.5
Best-practice grade
A92.0

Install command

npx @skill-hub/cli install openclaw-skills-aholake-expense-tracker

Repository

openclaw/skills

Skill path: skills/aholake/aholake-expense-tracker

Track daily expenses in structured markdown files organized by month. Use when the user wants to log spending, view expense summaries, analyze spending patterns, or manage personal finance tracking. Supports categories, tags, and monthly summaries.

Open repository

Best for

Primary workflow: Ship Full Stack.

Technical facets: Full Stack.

Target audience: everyone.

License: Unknown.

Original source

Catalog source: SkillHub Club.

Repository owner: openclaw.

This is still a mirrored public skill entry. Review the repository before installing into production workflows.

What it helps with

  • Install expense-tracker into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
  • Review https://github.com/openclaw/skills before adding expense-tracker to shared team environments
  • Use expense-tracker for development workflows

Works across

Claude CodeCodex CLIGemini CLIOpenCode

Favorites: 0.

Sub-skills: 0.

Aggregator: No.

Original source / Raw SKILL.md

---
name: expense-tracker
description: Track daily expenses in structured markdown files organized by month. Use when the user wants to log spending, view expense summaries, analyze spending patterns, or manage personal finance tracking. Supports categories, tags, and monthly summaries.
---

# Expense Tracker

Log and track daily expenses in markdown files organized by month.

## Quick Start

### Log an expense

```bash
python3 scripts/log_expense.py log <amount> <category> [--description "text"] [--tags "tag1,tag2"] [--date YYYY-MM-DD]
```

Examples:

```bash
# Simple expense
python3 scripts/log_expense.py log 45000 Coffee

# With description
python3 scripts/log_expense.py log 250000 Dining --description "Lunch with team"

# With tags
python3 scripts/log_expense.py log 500000 Shopping --tags "clothes,sale" --description "New shirt"

# Specify date (for backdating)
python3 scripts/log_expense.py log 1200000 Vehicle --description "Gas" --date 2026-02-15
```

### View monthly summary

```bash
# Current month
python3 scripts/log_expense.py summary

# Specific month
python3 scripts/log_expense.py summary 2026-02

# JSON output (for parsing)
python3 scripts/log_expense.py summary 2026-02 --json
```

## File Organization

Expenses are stored in `expenses/` directory at workspace root:

```
expenses/
├── 2026-01.md
├── 2026-02.md
└── 2026-03.md
```

Each file contains a markdown table:

```markdown
# Expenses - 2026-02

| Date | Category | Amount (VND) | Description | Tags |
|------|----------|-------------|-------------|------|
| 2026-02-17 | Coffee | 45,000 | | |
| 2026-02-17 | Dining | 250,000 | Lunch with team | |
| 2026-02-17 | Shopping | 500,000 | New shirt | clothes,sale |
```

## Categories

See `references/categories.md` for common expense categories. Use existing categories or create custom ones as needed.

Common categories:
- **Housing** - Rent, utilities, home expenses
- **Vehicle** - Gas, maintenance, parking
- **Dining** - Restaurants, food delivery
- **Coffee** - Cafes, coffee shops
- **Shopping** - Clothes, electronics, general purchases
- **Entertainment** - Movies, games, hobbies
- **Healthcare** - Medicine, doctor visits
- **Subscriptions** - Netflix, Spotify, gym, apps
- **Savings** - Investments, emergency fund
- **Debt Payment** - Loans, credit cards
- **Miscellaneous** - Other expenses

## Workflow Examples

### Log daily expenses from conversation

When the user mentions spending money:

```bash
# User: "Just paid 35k for coffee"
python3 scripts/log_expense.py log 35000 Coffee

# User: "Grabbed lunch for 120k at Phở 24"
python3 scripts/log_expense.py log 120000 Dining --description "Phở 24"

# User: "Filled up gas, 400k"
python3 scripts/log_expense.py log 400000 Vehicle --description "Gas"
```

### Monthly review

```bash
# Get summary
python3 scripts/log_expense.py summary 2026-02

# Read the expense file to see details
cat expenses/2026-02.md
```

### Analyze spending patterns

```bash
# Get JSON for analysis
python3 scripts/log_expense.py summary 2026-02 --json

# Compare multiple months
python3 scripts/log_expense.py summary 2026-01 --json > jan.json
python3 scripts/log_expense.py summary 2026-02 --json > feb.json
```

## Tips

- **Batch logging**: User can tell you multiple expenses at once, log them all
- **Category consistency**: Use the same category names to enable accurate summaries
- **Tags for filtering**: Use tags for subcategories (e.g., "work", "weekend", "urgent")
- **Descriptions**: Add context that helps identify the expense later
- **Regular reviews**: Suggest monthly summaries to track spending patterns

## Integration with Financial Goals

When tracking expenses, consider:

1. **Budget tracking**: Compare monthly totals to target budget
2. **Spending patterns**: Identify high-spend categories
3. **Emergency fund**: Track savings progress
4. **Debt reduction**: Monitor debt payment progress
5. **Financial ratios**: Calculate expenses as % of income

## Script Reference

### log_expense.py

**Commands:**
- `log` - Add an expense entry
- `summary` - View monthly summary

**Arguments (log):**
- `amount` - Amount in VND (required)
- `category` - Category name (required)
- `--description/-d` - Optional description
- `--tags/-t` - Optional comma-separated tags
- `--date` - Optional date (YYYY-MM-DD, defaults to today)
- `--workspace` - Optional workspace path (defaults to ~/.openclaw/workspace)

**Arguments (summary):**
- `year_month` - Optional YYYY-MM (defaults to current month)
- `--json` - Output as JSON
- `--workspace` - Optional workspace path

**Output:**
- Creates/updates markdown files in `expenses/` directory
- Prints confirmation with file location
- Summary shows total, count, and breakdown by category


---

## Referenced Files

> The following files are referenced in this skill and included for context.

### scripts/log_expense.py

```python
#!/usr/bin/env python3
"""
Log daily expenses to markdown files organized by month.
"""

import json
import argparse
from datetime import datetime
from pathlib import Path


def get_expense_file(year_month: str, workspace_path: str = None) -> Path:
    """Get the path to the expense file for a given month."""
    if workspace_path is None:
        workspace_path = Path.home() / ".openclaw" / "workspace"
    else:
        workspace_path = Path(workspace_path)
    
    expenses_dir = workspace_path / "expenses"
    expenses_dir.mkdir(exist_ok=True)
    
    return expenses_dir / f"{year_month}.md"


def init_expense_file(file_path: Path, year_month: str):
    """Initialize a new expense file with headers."""
    content = f"""# Expenses - {year_month}

| Date | Category | Amount (VND) | Description | Tags |
|------|----------|-------------|-------------|------|
"""
    file_path.write_text(content)


def log_expense(amount: float, category: str, description: str = "", tags: str = "", 
                date: str = None, workspace_path: str = None):
    """Log an expense entry."""
    if date is None:
        date = datetime.now().strftime("%Y-%m-%d")
    
    year_month = date[:7]  # YYYY-MM
    file_path = get_expense_file(year_month, workspace_path)
    
    # Initialize file if it doesn't exist
    if not file_path.exists():
        init_expense_file(file_path, year_month)
    
    # Format amount with thousand separators
    amount_str = f"{amount:,.0f}"
    
    # Create expense entry
    entry = f"| {date} | {category} | {amount_str} | {description} | {tags} |\n"
    
    # Append to file
    with file_path.open("a") as f:
        f.write(entry)
    
    print(f"✓ Logged expense: {amount_str} VND ({category})")
    print(f"  File: {file_path}")
    
    return str(file_path)


def get_monthly_summary(year_month: str, workspace_path: str = None) -> dict:
    """Get summary of expenses for a month."""
    file_path = get_expense_file(year_month, workspace_path)
    
    if not file_path.exists():
        return {"total": 0, "by_category": {}, "count": 0}
    
    content = file_path.read_text()
    lines = content.strip().split("\n")[3:]  # Skip header
    
    total = 0
    by_category = {}
    count = 0
    
    for line in lines:
        if not line.strip() or line.startswith("|---"):
            continue
        
        parts = [p.strip() for p in line.split("|")[1:-1]]
        if len(parts) < 3:
            continue
        
        try:
            amount = float(parts[2].replace(",", ""))
            category = parts[1]
            
            total += amount
            by_category[category] = by_category.get(category, 0) + amount
            count += 1
        except (ValueError, IndexError):
            continue
    
    return {
        "total": total,
        "by_category": by_category,
        "count": count,
        "file": str(file_path)
    }


def main():
    parser = argparse.ArgumentParser(description="Log daily expenses")
    subparsers = parser.add_subparsers(dest="command", help="Command to run")
    
    # Log command
    log_parser = subparsers.add_parser("log", help="Log an expense")
    log_parser.add_argument("amount", type=float, help="Amount in VND")
    log_parser.add_argument("category", help="Expense category")
    log_parser.add_argument("--description", "-d", default="", help="Description")
    log_parser.add_argument("--tags", "-t", default="", help="Tags (comma-separated)")
    log_parser.add_argument("--date", help="Date (YYYY-MM-DD, defaults to today)")
    log_parser.add_argument("--workspace", help="Workspace path")
    
    # Summary command
    summary_parser = subparsers.add_parser("summary", help="Get monthly summary")
    summary_parser.add_argument("year_month", nargs="?", help="Year-month (YYYY-MM, defaults to current month)")
    summary_parser.add_argument("--workspace", help="Workspace path")
    summary_parser.add_argument("--json", action="store_true", help="Output as JSON")
    
    args = parser.parse_args()
    
    if args.command == "log":
        log_expense(
            args.amount,
            args.category,
            args.description,
            args.tags,
            args.date,
            args.workspace
        )
    
    elif args.command == "summary":
        year_month = args.year_month or datetime.now().strftime("%Y-%m")
        summary = get_monthly_summary(year_month, args.workspace)
        
        if args.json:
            print(json.dumps(summary, indent=2))
        else:
            print(f"\n📊 Expense Summary - {year_month}")
            print(f"   Total: {summary['total']:,.0f} VND")
            print(f"   Transactions: {summary['count']}")
            print(f"\n   By Category:")
            for cat, amount in sorted(summary['by_category'].items(), key=lambda x: -x[1]):
                print(f"   • {cat}: {amount:,.0f} VND")
            print(f"\n   File: {summary.get('file', 'N/A')}")
    
    else:
        parser.print_help()


if __name__ == "__main__":
    main()

```

### references/categories.md

```markdown
# Expense Categories

Common categories for organizing expenses. Use these as guidelines; create custom categories as needed.

## Essential Living

- **Housing** - Rent, mortgage, property tax, home insurance
- **Utilities** - Electricity, water, gas, internet, phone
- **Groceries** - Food shopping, household supplies
- **Healthcare** - Doctor visits, medication, health insurance

## Transportation

- **Vehicle** - Car payment, motorcycle, gas, maintenance
- **Public Transport** - Bus, taxi, Grab, bike rental
- **Parking** - Parking fees, toll roads

## Food & Drink

- **Dining** - Restaurants, cafes, food delivery
- **Coffee** - Coffee shops, café work sessions
- **Snacks** - Convenience stores, street food

## Personal

- **Clothing** - Clothes, shoes, accessories
- **Personal Care** - Haircuts, toiletries, cosmetics
- **Entertainment** - Movies, games, hobbies
- **Subscriptions** - Netflix, Spotify, gym, apps

## Work & Education

- **Work Expenses** - Equipment, software, coworking
- **Education** - Courses, books, training
- **Professional** - Certifications, conferences

## Financial

- **Debt Payment** - Credit card, loans, installments
- **Savings** - Emergency fund, investments
- **Insurance** - Life, health, vehicle insurance
- **Fees** - Bank fees, transaction fees

## Shopping

- **Electronics** - Gadgets, computers, accessories
- **Home** - Furniture, appliances, decor
- **Gifts** - Presents, celebrations
- **Shopping** - General shopping, online purchases

## Lifestyle

- **Travel** - Vacation, trips, hotels
- **Fitness** - Gym, sports, equipment
- **Social** - Outings with friends, dates
- **Pet** - Pet food, vet, supplies

## Other

- **Miscellaneous** - Uncategorized expenses
- **Emergency** - Unexpected urgent expenses
- **Transfer** - Money sent to family/friends

## Custom Categories

Feel free to create categories specific to your lifestyle:
- **Investing** - Stock purchases, crypto
- **Side Hustle** - Business expenses
- **Content Creation** - Camera gear, software
- **Gaming** - Games, in-app purchases, equipment

```



---

## Skill Companion Files

> Additional files collected from the skill directory layout.

### _meta.json

```json
{
  "owner": "aholake",
  "slug": "aholake-expense-tracker",
  "displayName": "Expense Tracker",
  "latest": {
    "version": "1.0.0",
    "publishedAt": 1771285560987,
    "commit": "https://github.com/openclaw/skills/commit/63c33d4fb3eb134ee5eda88feb096fe6e2259b5a"
  },
  "history": []
}

```