Day 03 Applied Practice

Express Chat Server: Multi-User Conversations

Day 3 builds a production-ready Express chat server with session management, conversation history, and streaming — everything a real chat app needs.

~1 hour Hands-on Precision AI Academy

Today’s Objective

Day 3 builds a production-ready Express chat server with session management, conversation history, and streaming — everything a real chat app needs.

Express Chat Server: Multi-User Conversations is one of the most important topics in JavaScript + AI APIs. This lesson builds the foundation you need before moving to more advanced concepts — take time with each example and run the code yourself.

The Full Chat Server

server.js
SERVER.JS
import express from 'express';
import Anthropic from '@anthropic-ai/sdk';
import * as dotenv from 'dotenv';
import crypto from 'crypto';
dotenv.config();

const app = express();
const client = new Anthropic();
const sessions = new Map();

app.use(express.json());
app.use(express.static('public'));

// Create or retrieve session
app.post('/session', (req, res) => { const sessionId = crypto.randomUUID(); sessions.set(sessionId, { messages: [], createdAt: Date.now() }); res.json({ sessionId });
});

// Streaming chat endpoint
app.post('/chat', async (req, res) => { const { message, sessionId } = req.body; if (!sessions.has(sessionId)) { return res.status(400).json({ error: 'Invalid session' }); } const session = sessions.get(sessionId); session.messages.push({ role: 'user', content: message }); res.setHeader('Content-Type', 'text/event-stream'); res.setHeader('Cache-Control', 'no-cache'); let fullResponse = ''; try { const stream = await client.messages.stream({ model: 'claude-opus-4-5', max_tokens: 2048, system: 'You are a helpful assistant. Be clear and concise.', messages: session.messages }); for await (const chunk of stream) { if (chunk.type === 'content_block_delta' && chunk.delta.type === 'text_delta') { fullResponse += chunk.delta.text; res.write(`data: ${JSON.stringify({ text: chunk.delta.text })}

`); } } session.messages.push({ role: 'assistant', content: fullResponse }); res.write('data: [DONE]

'); } catch (error) { res.write(`data: ${JSON.stringify({ error: error.message })}

`); } res.end();
});

// Clear session history
app.delete('/session/:id', (req, res) => { sessions.delete(req.params.id); res.json({ success: true });
});

// Cleanup old sessions every hour
setInterval(() => { const cutoff = Date.now() - 60 * 60 * 1000; for (const [id, session] of sessions.entries()) { if (session.createdAt < cutoff) sessions.delete(id); }
}, 60 * 60 * 1000);

app.listen(3000, () => console.log('Chat server on port 3000'));
Day 3 ExerciseTest Multi-User Sessions
  1. Run the server and open two browser tabs.
  2. Start a conversation in tab 1 about topic A. Start a conversation in tab 2 about topic B.
  3. Verify the conversations are independent — tab 1 does not know about tab 2's conversation.
  4. Test the session delete endpoint — verify history clears when called.
  5. Add a custom system prompt and test how it changes the chatbot's behavior.

Supporting Resources

Go deeper with these references.

Anthropic
Claude API Reference Official documentation for the Messages API, tool use, and streaming.
npm
@anthropic-ai/sdk Official Node.js SDK for the Anthropic API with TypeScript support.
GitHub
Anthropic Cookbook Official Anthropic code examples for common JavaScript + Claude patterns.

Day 3 Checkpoint

Before moving on, make sure you can answer these without looking:

Continue To Day 4
Document Processing: Analyze Files with AI