Study Portal Logo Infokept Career Hub

Project- Personal Expense Tracker

Updated: 29 Jul 2026, 11:08:19

Project- Personal Expense Tracker

Project Contents

Personal-Expense-Tracker/
│
├── index.html
├── style.css
├── script.js
├── storage.js
├── data.json
└── README.txt
 

Features

  • ✅ Add Income
  • ✅ Add Expense
  • ✅ Delete Transaction
  • ✅ Search Transactions
  • ✅ Balance Calculation
  • ✅ Loads sample data from data.json
  • ✅ Saves changes in Local Storage
  • ✅ Pure HTML, CSS, JavaScript (no frameworks)

File 1: index.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Personal Expense Tracker</title>

    <link rel="stylesheet" href="style.css">
</head>

<body>

    <h1>Personal Expense Tracker</h1>

    <form id="f">

        <input
            type="text"
            id="d"
            placeholder="Description"
            required>

        <input
            type="number"
            id="a"
            placeholder="Amount"
            required>

        <select id="t">
            <option>Income</option>
            <option>Expense</option>
        </select>

        <button type="submit">
            Add
        </button>

    </form>

    <input
        type="text"
        id="s"
        placeholder="Search">

    <div id="bal"></div>

    <table>

        <thead>

            <tr>
                <th>Description</th>
                <th>Amount</th>
                <th>Type</th>
                <th>Action</th>
            </tr>

        </thead>

        <tbody id="tb">

        </tbody>

    </table>

    <script src="storage.js"></script>
    <script src="script.js"></script>

</body>

</html>

File2:  style.css

 

body {
    font-family: Arial, Helvetica, sans-serif;
    max-width: 800px;
    margin: auto;
    padding: 20px;
}

 

input,
select,
button {
    margin: 5px;
    padding: 8px;
}

 

table {
    width: 100%;
    border-collapse: collapse;
}

 

td,
th {
    border: 1px solid #ccc;
    padding: 6px;
}

 

file 3: script.js

let data = [];

// Initialize the application
async function init() {

    data = load() || await (await fetch("data.json")).json();

    render();

}

// Render all transactions
function render(f = data) {

    tb.innerHTML = "";

    let bal = 0;

    f.forEach((x, i) => {

        bal += (x.type == "Income")
            ? +x.amount
            : -x.amount;

        tb.innerHTML += `
            <tr>
                <td>${x.description}</td>
                <td>${x.amount}</td>
                <td>${x.type}</td>
                <td>
                    <button onclick="del(${i})">
                        X
                    </button>
                </td>
            </tr>
        `;

    });

    document.getElementById("bal").textContent =
        "Balance: " + bal;

}

// Add new transaction
f.onsubmit = (e) => {

    e.preventDefault();

    data.push({

        description: d.value,

        amount: +a.value,

        type: t.value

    });

    save(data);

    render();

    f.reset();

};

// Delete transaction
function del(i) {

    data.splice(i, 1);

    save(data);

    render();

}

// Search transactions
s.oninput = () => {

    render(

        data.filter(x =>

            x.description
                .toLowerCase()
                .includes(
                    s.value.toLowerCase()
                )

        )

    );

};

// Start application
init();

File 4: storage.js

/* ==========================
   Local Storage Functions
   ========================== */

/**
 * Save all expense records to Local Storage
 * @param {Array} data - Array of expense objects
 */
function save(data) {
    localStorage.setItem(
        "expenses",
        JSON.stringify(data)
    );
}

/**
 * Load expense records from Local Storage
 * @returns {Array|null}
 */
function load() {
    return JSON.parse(
        localStorage.getItem("expenses") || "null"
    );
}

File 5: data.json

[
    {
        "description": "Salary",
        "amount": 5000,
        "type": "Income"
    },
    {
        "description": "Groceries",
        "amount": 200,
        "type": "Expense"
    }
]

File 6: readme.txt

Open with Live Server. Uses HTML,CSS,JS,JSON and localStorage.

 

About Author

Swarnim Raj - Author Infokept Career Hub

Swarnim Raj

Author & Career Content Writer

Experienced education and career writer at Infokept Career Hub, creating simple, research-based guides for students and government job aspirants.

Search Related Topics