TaskCraft
A task and project manager for a small team, written in plain JavaScript, with a mock REST backend that enforces who can do what.
- Live demo
- 2026
At a glance
- Why it matters
- A small team gets projects, a board and roles that are enforced by the backend, so a member cannot edit or delete someone else's work.
- My role
- Solo, end to end
- Stack
- JavaScript, HTML, CSS, Chart.js
The problem
Most task tools are either a list with no rules or a product so large that setting it up becomes a project of its own. I wanted the middle: projects, tasks and a board, with roles that actually stop a member from deleting someone else's work.
I also wanted to build it without a framework, to see how far plain JavaScript goes when the structure is kept strict.
What it does
TaskCraft has a dashboard, a task list and a kanban board with drag and drop, projects with their own progress and hours, a team page, analytics and notifications. A search box finds tasks and projects, and the top bar scopes everything to one project.
There are three roles. An admin can do everything, a manager cannot delete projects or manage the team, and a member can only edit their own tasks. You can switch person in Settings and watch the interface change. Simulated teammates move tasks every twenty seconds or so, so the dashboard changes while you look at it.
Captures




How it works
Views never talk to the data directly
Views
- components/*.jsDashboard, tasks, board, projects, team, settings
- router.jsHash routes, one view at a time
Services
- taskService.js and othersOne per resource. The only layer views call
HTTP seam
- httpClient.jsSpeaks REST. Mock today, fetch to a real server later
Mock backend
- mockServer.jsRoutes, validation, permissions, 403 answers
- storage.jsThe database, kept in localStorage
- realtime.jsEvents a WebSocket would deliver
Drawn from the js folder. Each layer only calls the one below it.
Decisions
Permissions live on the server side
The mock API checks every call against the role and answers 403 when it is not allowed. The interface hides or disables what a role cannot do, but that is a courtesy. The rule is enforced underneath it.
One seam to a real backend
Views call services, services call one HTTP client, and only that client knows the backend is a mock. The docs folder describes the REST contract and a PostgreSQL schema, so replacing the mock changes one file.
Everything rendered is escaped
Views are template strings, so every value goes through one escaping function. Routing reads only a page name and an id from the address, and those are matched against fixed patterns.
No build step to run it
It is classic scripts in a fixed order. It opens from a file on disk. For the public demo the scripts are minified and Chart.js and the font are served from the same site.