// projects.nodejs
10 Best Node JS Projects
Hand-picked and ordered easiest → hardest — each with complete code and expected output. Build these to turn lessons into a portfolio.
Back to Node JS course
// solution.code
node.js
// REST API with Express and File Storage
// A task management API using JSON file persistence
const express = require('express');
const fs = require('fs').promises;
const path = require('path');
const app = express();
const PORT = 3000;
const DATA_FILE = path.join(__dirname, 'tasks.json');
// Middleware
app.use(express.json());
// Initialize data file if it doesn't exist
const initDataFile = async () => {
try {
await fs.access(DATA_FILE);
} catch {
await fs.writeFile(DATA_FILE, JSON.stringify([]));
}
};
// Helper to read tasks
const readTasks = async () => {
const data = await fs.readFile(DATA_FILE, 'utf8');
return JSON.parse(data);
};
// Helper to write tasks
const writeTasks = async (tasks) => {
await fs.writeFile(DATA_FILE, JSON.stringify(tasks, null, 2));
};
// GET all tasks
app.get('/api/tasks', async (req, res) => {
try {
const tasks = await readTasks();
res.json(tasks);
} catch (error) {
res.status(500).json({ error: 'Failed to read tasks' });
}
});
// POST create task
app.post('/api/tasks', async (req, res) => {
try {
const tasks = await readTasks();
const newTask = {
id: Date.now().toString(),
title: req.body.title,
completed: false,
createdAt: new Date().toISOString()
};
tasks.push(newTask);
await writeTasks(tasks);
res.status(201).json(newTask);
} catch (error) {
res.status(500).json({ error: 'Failed to create task' });
}
});
// PUT update task
app.put('/api/tasks/:id', async (req, res) => {
try {
const tasks = await readTasks();
const index = tasks.findIndex(t => t.id === req.params.id);
if (index === -1) return res.status(404).json({ error: 'Task not found' });
tasks[index] = { ...tasks[index], ...req.body };
await writeTasks(tasks);
res.json(tasks[index]);
} catch (error) {
res.status(500).json({ error: 'Failed to update task' });
}
});
// DELETE task
app.delete('/api/tasks/:id', async (req, res) => {
try {
const tasks = await readTasks();
const filtered = tasks.filter(t => t.id !== req.params.id);
if (tasks.length === filtered.length) return res.status(404).json({ error: 'Task not found' });
await writeTasks(filtered);
res.status(204).send();
} catch (error) {
res.status(500).json({ error: 'Failed to delete task' });
}
});
// Start server
initDataFile().then(() => {
app.listen(PORT, () => console.log(`Task API running on port ${PORT}`));
}); output
Task API running on port 3000
Test with curl:
$ curl -X POST http://localhost:3000/api/tasks -H "Content-Type: application/json" -d '{"title":"Learn Node.js"}'
{"id":"1704067200000","title":"Learn Node.js","completed":false,"createdAt":"2024-01-01T00:00:00.000Z"}
$ curl http://localhost:3000/api/tasks
[{"id":"1704067200000","title":"Learn Node.js","completed":false,"createdAt":"2024-01-01T00:00:00.000Z"}]