π’
EPISODE 06
Persisting state Β· read/write JSON Β· race conditions
File-based Database (JSON)
Before introducing a real database, persist data to disk as JSON. Learn the limitations (concurrency, scale) and when to graduate to SQLite/PostgreSQL.
persistenceJSONfslowdb
Duration
β± About 1.5 hours
Level
π Intermediate
Prerequisite
π― node-05
OUTCOME
Persist a REST API's data to a JSON file (good enough for prototypes)
What you'll learn
- 1Read/write a JSON file with fs.promises
- 2Wrap I/O in helper functions
- 3Recognize race-condition limitations
- 4Migrate naturally to a real database later
1. A Tiny JSON Store
javascript
import fs from "node:fs/promises";
const FILE = "./data.json";
async function load() {
try {
return JSON.parse(await fs.readFile(FILE, "utf8"));
} catch {
return { tasks: [], nextId: 1 };
}
}
async function save(data) {
await fs.writeFile(FILE, JSON.stringify(data, null, 2));
}
const db = await load();
db.tasks.push({ id: db.nextId++, title: "buy milk" });
await save(db);2. Integrate with Express
javascript
app.get("/tasks", async (req, res) => {
const db = await load();
res.json(db.tasks);
});
app.post("/tasks", async (req, res) => {
const db = await load();
const task = { id: db.nextId++, title: req.body.title, done: false };
db.tasks.push(task);
await save(db);
res.status(201).json(task);
});3. Limitations
- Two requests writing at the same time can lose data (race condition)
- Whole file is read/rewritten on every operation β slow past a few MB
- No query language, no indexes
- Fine for: personal tools, prototypes, low-traffic dashboards
- Not fine for: any production app with concurrent users
π‘
Next module β Databases β graduates from JSON to SQLite (single file but with SQL) and beyond.
Example code / lecture materials
All lecture materials and example code are openly available on GitHub.
View on GitHub β