Node.js is a free, open-source, cross-platform JavaScript runtime environment that enables developers to create servers, web applications, command-line tools, and scripts. The Windows installation package can be downloaded here: https://nodejs.org/en.
We are going to use VS Code as the development environment, first enter the following command in the command line:
npm init -y
This command initializes the development environment, and after executing it, you can see that a package.json file has been generated in the project folder.

The package.json
file is the central configuration file for a Node.js project. It contains metadata about the project and manages its dependencies, scripts, and other configurations.
Main functions:
- Metadata: Includes project name, version, description, author, and license information.
- Dependency Management: Lists project dependencies under dependencies and development dependencies under devDependencies. Specifies version ranges for each dependency (e.g., ^1.0.0, ~1.0.0, >=1.0.0).
- Scripts: Allows you to define custom commands that can be run using npm run . Example: “start”: “node server.js”
Compatibility: Others can use it to install necessary dependencies using npm install.
Enter the following command to install the Express server framework::
npm install express
Create a public folder in the project directory, and then create index.html, scripts.js, and style.css inside the folder to build the web interface, interaction logic, and style decoration. Additionally, create a .env file to store API keys.。

Overall, the Node.js file structure is similar to Flask, and if you are familiar with Flask development, you can easily understand the underlying logic.
I remember that JavaScript was previously only used for web frontend development, writing interactions and such. I didn’t expect that now it can handle both frontend and backend, enabling full-stack development.
Create a server.js file in the project root directory to test running the server, with the code as follows::
const express = require('express');
const app = express();
app.get('/', (req, res) => {
res.send('Hello World!');
});
const PORT = 3000;
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});
To run this code, simply enter node + filename in the terminal.

The server is successfully running on local port 3000.
Open a browser and enter localhost:3000 to see Hello World!, indicating that the server is running successfully.

Next, optimize the code to call index.html:
const express = require('express');
const path = require('path');
const app = express();
const port = 3000;
// Serve static files from the 'public' directory
app.use(express.static(path.join(__dirname, 'public')));
// Start the server
app.listen(port, () => {
console.log(`Server running at http://localhost:${port}`);
});
Write a simple index.html file:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hello World App</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>Hello, World!</h1>
<p>Welcome to the enhanced Node.js application.</p>
<button id="greetButton">Click Me</button>
<script src="script.js"></script>
</body>
</html>
In the script.js file, write simple interaction logic to display “Hello World!” when the button is clicked:
// Select the button
const greetButton = document.getElementById('greetButton');
// Add a click event listener to the button
greetButton.addEventListener('click', () => {
alert('Hello, World!');
});
Press ctrl+c to pause the server, then run it again and open a browser to access localhost:3000:

Click “Click Me” to display Hello World!

The above is a basic introduction to Node.js Express framework server development, which is relatively easy to get started with. Next, let’s look at how to build a simple AI chat website using this framework, taking ChatGPT as an example.
First, install new dependency packages::
npm install body-parser openai dotenv
OpenAI needs no introduction, body-parser is a middleware used to handle various data types like JSON and text. dotenv is used to read API keys.
Server-side server.js code is as follows:
const express = require('express');
const path = require('path');
const bodyParser = require('body-parser');
const OpenAI = require('openai');
require('dotenv').config();
const app = express();
const port = 3000;
// Configure OpenAI API
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY
});
// Middleware
app.use(express.static(path.join(__dirname, 'public')));
app.use(bodyParser.json());
// API endpoint to handle AI response
app.post('/ask', async (req, res) => {
const userPrompt = req.body.prompt;
try {
const response = await openai.chat.completions.create({
model: 'gpt-4',
messages: [{
role: 'user',
content: userPrompt
}],
});
const aiMessage = response.choices[0].message.content;
res.json({ reply: aiMessage });
} catch (error) {
console.error('Error:', error);
res.status(500).json({ error: 'Failed to get response from AI' });
}
});
// Start the server
app.listen(port, () => {
console.log(`Server running at http://localhost:${port}`);
});
Those require statements are like Python’s import, importing various modules. Then read the OpenAI API key from .env. The core program is this section, inputting a prompt as a user and calling the GPT-4o model.
const response = await openai.chat.completions.create({
model: 'gpt-4o',
messages: [{
role: 'user',
content: userPrompt
HTML code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ChatGPT Web App</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>Chat with AI</h1>
<textarea id="userPrompt" placeholder="Enter your prompt here..."></textarea>
<button id="askButton">Ask AI</button>
<div id="responseContainer">
<h3>Response:</h3>
<p id="aiResponse"></p>
</div>
<script src="script.js"></script>
</body>
</html
Interaction logic script.js:
const askButton = document.getElementById('askButton');
const userPrompt = document.getElementById('userPrompt');
const aiResponse = document.getElementById('aiResponse');
askButton.addEventListener('click', async () => {
const prompt = userPrompt.value;
if (!prompt.trim()) {
aiResponse.textContent = 'Please enter a prompt.';
return;
}
try {
const response = await fetch('/ask', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ prompt }),
});
const data = await response.json();
if (response.ok) {
aiResponse.textContent = data.reply;
} else {
aiResponse.textContent = 'Error: ' + (data.error || 'Failed to fetch response.');
}
} catch (error) {
console.error('Error:', error);
aiResponse.textContent = 'An error occurred. Please try again.';
}
});
CSS style code:
body {
font-family: Arial, sans-serif;
text-align: center;
margin-top: 50px;
background-color: #f4f4f9;
color: #333;
}
h1 {
color: #007bff;
}
textarea {
width: 80%;
height: 100px;
margin: 10px 0;
padding: 10px;
font-size: 16px;
border: 1px solid #ddd;
border-radius: 5px;
}
button {
background-color: #007bff;
color: white;
padding: 10px 20px;
border: none;
border-radius: 5px;
font-size: 16px;
cursor: pointer;
}
button:hover {
background-color: #0056b3;
}
#responseContainer {
margin-top: 20px;
}
#responseContainer h3 {
margin-bottom: 5px;
}
#aiResponse {
font-size: 16px;
color: #555;
}
Running interface:


This AI only completes a single conversation without context memory. To implement context memory, you can call some memory-related functions from Langchain. The updated server-side code is as follows, with no need to modify the frontend and interaction logic code:
const { ChatOpenAI } = require("@langchain/openai");
const { BufferMemory } = require("langchain/memory");
const { ConversationChain } = require("langchain/chains");
const bodyParser = require('body-parser');
const express = require('express');
const path = require('path');
const app = express();
const port = 3000;
require('dotenv').config();
// Middleware
app.use(express.static(path.join(__dirname, 'public')));
app.use(bodyParser.json());
const chatModel = new ChatOpenAI({
openAIApiKey: process.env.OPENAI_API_KEY,
modelName: 'gpt-4',
temperature: 0.7
});
const memory = new BufferMemory();
const chain = new ConversationChain({
llm: chatModel,
memory: memory
});
app.post('/ask', async (req, res) => {
try {
const response = await chain.call({
input: req.body.prompt
});
res.json({ reply: response.response });
} catch (error) {
console.error('Error:', error);
res.status(500).json({ error: 'Failed to get response' });
}
});
// Start the server
app.listen(port, () => {
console.log(`Server running at http://localhost:${port}`);
});
Test results:


