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 & Career Content Writer
Experienced education and career writer at Infokept Career Hub, creating simple, research-based guides for students and government job aspirants.