Todos
Every action here is a plain HTML form, so the page works with JavaScript switched off. When JavaScript is on, those same forms post without a reload and the server sends back just the row that changed—no virtual DOM, no client-side templates, no second copy of the markup, full reactivity.
Try it out
Open the network tab and add a task. The response is one row of HTML, not a page.
2 items left
Log in to delete todos—the delete column only renders for authenticated users, showing how auth gates both controller logic and template output.
| Done | Todo |
|---|---|
| Read the README | |
| Add a todo without a page reload | |
| Ship it | |
| Nothing to show. | |
API Endpoints
The same service layer backs both the HTML forms above and the JSON API below—adding an API is simple when business logic lives in one place.
| GET | /api/todos | List todos (paginated—?limit=, ?offset=) |
| POST | /api/todos | Create a todo |
| GET | /api/todos/:id | Get one todo |
| PUT | /api/todos/:id | Rename, and optionally set completed |
| DELETE | /api/todos/:id | Delete a todo |