Claude Code Todo
This chapter walks you through from opening the terminal to running a complete Todo REST API, entirely driven by Claude Code + DeepSeek V4.
Claude Code + DeepSeek V4 Configuration Reference: (https://example.com/claude-code/claude-code-deepseek.html)
Let's first look at the basic operation interface of Claude Code and common high-frequency commands.
### Start Your First Claude Code Session
Open the terminal, enter any working directory (or create a new empty folder), then enter:
$ mkdir tutorial-todo-api $ cd tutorial-todo-api $ claude
On first launch, you will see a welcome screen, version information, and DeepSeek environment variable configuration.
!(https://example.com/wp-content/uploads/2026/05/tutorial_1779254890182.png)
> If you're not sure whether the configuration has taken effect, immediately enter /status after entering and confirm that the Base URL points to https://api.deepseek.com/anthropic.
### Common Slash Commands Quick Reference
In Claude Code's dialog box, commands starting with / are built-in commands and will not be sent to the model.
| Command | Function |
| --- | --- |
| /status | View current model, Base URL, session statistics |
| /help | Display all available commands |
| /clear | Clear current conversation context (without deleting files) |
| /exit or Ctrl+C | Exit Claude Code |
| /undo | Undo last file modification |
| /diff | View git diff of the most recent modification |
### Permission Prompt Mechanism
When Claude Code is about to write files or execute commands, it will first pause, list the operations to be performed, and wait for your confirmation.
This is the most important security mechanism of Claude Code - beginners don't need to worry about AI going out of control and making random changes.
You will see prompts like this:
ββββββββββββββββββββββββββββββββββββββββββββββββββββ Claude wants to create the following files: ββ ββ β’ src/index.js ββ β’ src/routes/todos.js ββ β’ package.json ββ ββ Allow? [Y/n] ββββββββββββββββββββββββββββββββββββββββββββββββββββ
Simply press Enter or type y to confirm, type n to skip.
* * *
## Hands-on Project: Build a Todo API from Scratch with AI
This section guides you through using natural language to drive Claude Code and generate a runnable Node.js REST API from scratch.
### Project Goal
We need to build a REST API with the following functions:
| Endpoint | Function |
| --- | --- |
| GET /todos | Get all todo items |
| POST /todos | Create a new todo item |
| PUT /todos/:id | Update a todo item (mark as complete/modify content) |
| DELETE /todos/:id | Delete a todo item |
Tech Stack: Node.js + Express, data temporarily stored in memory (no database needed to reduce complexity).
### Step 1: Describe Requirements in Natural Language
Enter the following in Claude Code's dialog box (just copy and paste):
Please help me create a Node.js + Express Todo REST API project from scratch. Requirements:- Support GET /todos, POST /todos, PUT /todos/:id, DELETE /todos/:id four endpoints- Store data in a memory array first, no database needed- Each todo should contain: id, title, completed (boolean), createdAt fields- Use JSON format for both requests and responses- Add basic error handling (404, 400, etc.)- Generate a README.md explaining how to start and test the endpointsProject structure suggestion:my-todo-api/βββ src/β βββ index.js # Entry fileβ βββ routes/β βββ todos.js # Todo routesβββ package.json βββ README.md
!(https://example.com/wp-content/uploads/2026/05/tutorial_1779255024375.png)
> The three key elements of writing a good prompt: context (tell the AI the tech stack and project background), constraints (clarify what you don't want - clarify what you don't want), expected output (give specific file structure or format requirements).
### Step 2: Claude Code Generates File Structure
After confirming permissions, Claude Code will create the following files in sequence.
During generation, there are many permission confirmations, generally just select Yes:
!(https://example.com/wp-content/uploads/2026/05/tutorial_1779255121552.png)
After success, there will be output information as follows, including generated content, startup information, etc., very detailed:
!(https://example.com/wp-content/uploads/2026/05/tutorial_1779255283065.png)
Let's check the generated project structure:
!(https://example.com/wp-content/uploads/2026/05/tutorial_1779255669956.png)
#### package.json
## Example
{
"name":"my-todo-api",
"version":"1.0.0",
"description":"A simple Todo REST API built with Express",
"main":"src/index.js",
"scripts":{
"start":"node src/index.js",
"dev":"nodemon src/index.js"
},
"dependencies":{
"express":"^4.18.2"
},
"devDependencies":{
"nodemon":"^3.0.1"
}
}
#### src/index.js (Entry File)
## Example
// File path: src/index.js
// Todo API entry file, responsible for Express app configuration and startup
const express = require('express');
const todosRouter = require('./routes/todos');
const app = express();
// Port: prioritize environment variable PORT, default 3000
const PORT = process.env.PORT||3000;
// Middleware: parse JSON request body (required, otherwise req.body will be undefined)
app.use(express.json());
// Register Todo router, all /todos path requests handled by todosRouter
app.use('/todos', todosRouter);
// Root path: return welcome message and version number
app.get('/',(req, res)=>{
res.json({ message:'Todo API is running!', version:'1.0.0'});
});
// Global error handling middleware (required, catches unhandled exceptions)
app.use((err, req, res, next)=>{
console.error(err.stack);
res.status(500).json({ error:'Internal Server Error'});
});
// Start HTTP server
app.listen(PORT,()=>{
console.log(`Server is running on http://localhost:${PORT}`);
});
#### src/routes/todos.js (Core Route File)
## Example
// File path: src/routes/todos.js
// Todo route module, contains complete CRUD business logic
const express = require('express');
const router = express.Router();
// In-memory storage: use array to simulate database
// Data will be lost after service restart, can be replaced with SQLite for persistence later
let todos =[];
// Auto-increment ID counter
let nextId =1;
// GET /todos β Get all todo items
router.get('/',(req, res)=>{
res.json(todos);
});
// POST /todos β Create new todo item
router.post('/',(req, res)=>{
const{ title }= req.body;
// Parameter validation: title is required, must be string and not empty
if(!title ||typeof title !=='string'|| title.trim()===''){
return res.status(400).json({ error:'title Fieldcannotisempty'});
}
// Build new todo object
const newTodo ={
id: nextId++,// Auto-increment ID
title: title.trim(),// Trim leading/trailing spaces
completed:false,// Newly created todo defaults to incomplete
createdAt:new Date().toISOString(),// ISO 8601 format timestamp
};
todos.push(newTodo);
// 201 Created indicates successful resource creation
res.status(201).json(newTodo);
});
// PUT /todos/:id β Update todo item
router.put('/:id',(req, res)=>{
// Convert path parameter from string to number
const id = parseInt(req.params.id);
const todo = todos.find(t => t.id=== id);
// 404: resource not found
if(!todo){
return res.status(404).json({ error: `Not found id is ${id} todo items` });
}
const{ title, completed }= req
YouTip