A beginner-friendly full-stack task management application built with React, Node.js, Express, and PostgreSQL.
The project is intentionally organized so a learner can follow the request from the browser to the database:
React UI → service/API call → Express route → controller → model → PostgreSQL → API response → React UI
- Create, edit, complete, and delete tasks
- Task priority: low, medium, high
- Optional description and due date
- Search tasks
- Filter by active, completed, or all tasks
- Dashboard statistics
- Recent tasks
- Clear completed tasks
- Loading and error states
- Responsive UI
tiny-tasks/
├── backend/
│ ├── controllers/ # Validates requests and sends responses
│ ├── models/ # PostgreSQL queries
│ ├── routes/ # API endpoint definitions
│ ├── utils/ # Shared backend utilities
│ └── app.js # Express application entry point
├── database/
│ └── create-database.sql
├── frontend/
│ ├── src/
│ │ ├── components/ # Reusable UI components
│ │ ├── routes/ # Page-level components
│ │ ├── services/ # Frontend API functions
│ │ └── store/ # Shared React state
│ └── vite.config.js
├── .gitignore
├── package.json
└── pnpm-workspace.yaml
Install these before starting:
- Node.js
- pnpm
- PostgreSQL
- Git (needed later for GitHub)
Open pgAdmin and create a database named:
tiny_tasks_prashant
Then connect to that database and run the table/type/index section of:
database/create-database.sql
The
CREATE DATABASEline is for creating the database itself. Do not run it while already connected to that database.
From the project root:
pnpm installBecause this is a pnpm workspace, use pnpm install rather than npm install at the root.
Create a .env file inside backend/:
DATABASE_URL=postgresql://postgres:YOUR_PASSWORD@localhost:5432/tiny_tasks_prashant
PORT=8080Never put a real database password into GitHub. .env is already ignored by Git.
From the project root:
pnpm --filter backend run devThe API should run at:
http://localhost:8080
You can also open:
http://localhost:8080/api
and should see a JSON health message.
Open a second terminal in the project root:
pnpm --filter frontend run devOpen the URL Vite prints, normally:
http://localhost:5173
| Method | Endpoint | Purpose |
|---|---|---|
| GET | /api/todos |
List tasks |
| GET | /api/todos/:id |
Get one task |
| GET | /api/todos/stats |
Dashboard statistics |
| GET | /api/todos/recent |
Recent tasks |
| POST | /api/todos |
Create task |
| PATCH | /api/todos/:id |
Update task |
| DELETE | /api/todos/:id |
Delete task |
| DELETE | /api/todos/completed |
Delete completed tasks |
If you are learning this project from scratch, study it in this order:
frontend/src/routes/Home.jsx— understand the page and user actionsfrontend/src/components/TaskCard.jsx— understand reusable componentsfrontend/src/components/TaskModal.jsx— understand forms and validationfrontend/src/services/todoService.js— understand API requestsbackend/routes/todoRoutes.js— understand URL routingbackend/controllers/todoController.js— understand request validation and responsesbackend/models/todoModel.js— understand SQL and PostgreSQLdatabase/create-database.sql— understand the database structurefrontend/src/store/TodoContext.jsx— understand shared React statefrontend/src/main.jsx— understand how the application starts
Comments have been added only where they explain why something exists, how data moves, or what a non-obvious function is responsible for. Obvious code should remain readable without a comment.
Before pushing this project to GitHub:
- Test create, edit, complete, search, filter, delete, and clear-completed
- Confirm
.envis not tracked - Confirm
node_modules/anddist/are not tracked - Add screenshots to the README
- Make a clean Git commit
- Push the source code, not the ZIP file