Table of Contents
- What Is Express.js?
- What You Need Before Creating an Express.js App
- How to Create a Web App with Express.js
- Step 1: Create a New Project
- Step 2: Install Express.js
- Step 3: Create the Express Server
- Step 4: Add Routes
- Step 5: Add Middleware
- Step 6: Return JSON From an API
- Step 7: Add 404 and Error Handling
- Recommended Express.js Project Structure
- Using the Express Application Generator
- Express.js Best Practices
- FAQs
- Conclusion
What Is Express.js?
Express.js is a lightweight web framework for Node.js that provides routing, middleware, HTTP request handling, and other building blocks for developing web applications and APIs.
The framework is deliberately flexible. Express does not force developers to use one database, template engine, application architecture, or project structure. This makes it suitable for everything from a small learning project to a larger backend application.
Express 5 is the current major version, and the official documentation lists Node.js 18 or higher as a requirement. Express 5 retains the familiar Express API while introducing several changes and improvements over Express 4.
If you want to create a web app with Express.js, you can start with a single JavaScript file and add routes and middleware as your application grows.
What You Need Before Creating an Express.js App
Before starting an Express.js web app, install:
- Node.js
- npm, which is included with Node.js
- A code editor such as Visual Studio Code
- A web browser
- A terminal or command prompt
For a production project, use a supported Node.js LTS release. As of October 2026, the Node.js download page lists Node.js 24.x as an LTS line, while Node.js 26.x is the Current line.
Check your installation with:
node -v
npm -v
You can then create your first project.
How to Create a Web App with Express.js
Let’s build a small Express 5 application that returns HTML from one route and JSON from another.
Step 1: Create a New Project
Create a directory for your application and move into it:
mkdir my-express-app
cd my-express-app
Initialize a Node.js project:
npm init -y
This creates a package.json file containing your project’s basic metadata and dependencies.
The official Express installation guide follows the same general workflow: create a project directory, initialize it with npm, and install Express as a dependency.
Step 2: Install Express.js
Install Express with npm:
npm install express
This adds Express to your project’s dependencies.
You can verify the installed version with:
npm list express
For this tutorial, we’ll use Express 5.
You don’t need to install Express globally just to create an application. Installing it locally keeps the dependency associated with the project and allows the project to control its own dependency versions.
Step 3: Create the Express Server
Create a file named:
app.js
Add the following code:
const express = require(‘express’);
const app = express();
const port = 3000;
app.get(‘/’, (req, res) => {
res.send(‘Hello from Express.js!’);
});
app.listen(port, () => {
console.log(`Express app running at http://localhost:${port}`);
});
Start the application:
node app.js
Open the following address in your browser:
http://localhost:3000
You should see:
Hello from Express.js!
This is essentially the same architecture used in the official Express Hello World example. Express creates an application instance, defines a route, and starts an HTTP server listening on port 3000.
Step 4: Add Routes
An Express application can contain multiple routes.
For example:
app.get(‘/about’, (req, res) => {
res.send(‘About our application’);
});
app.get(‘/contact’, (req, res) => {
res.send(‘Contact us’);
});
Now your application responds to:
/
/about
/contact
Routes can also contain parameters.
app.get(‘/users/:id’, (req, res) => {
res.json({
userId: req.params.id
});
});
Visiting:
http://localhost:3000/users/42
returns:
{
“userId”: “42”
}
For larger applications, Express provides express.Router() so related routes can be separated into their own modules.
Step 5: Add Middleware
Middleware is one of the core concepts behind Express.
Middleware functions can inspect requests, modify responses, perform authentication, log activity, validate data, or pass control to another middleware function.
For example:
app.use(express.json());
This allows your application to parse incoming JSON request bodies.
You can also create custom middleware:
app.use((req, res, next) => {
console.log(`${req.method} ${req.url}`);
next();
});
The next() function passes control to the next middleware or route handler.
Express’s middleware architecture is one reason the framework remains flexible: applications can combine built-in middleware with application-specific and third-party middleware.
Step 6: Return JSON From an API
Express is commonly used to create backend APIs.
For example:
app.get(‘/api/products’, (req, res) => {
res.json([
{
id: 1,
name: ‘Laptop’
},
{
id: 2,
name: ‘Keyboard’
}
]);
});
Open:
http://localhost:3000/api/products
The server returns structured JSON that can be consumed by a frontend application, mobile application, or another service.
This makes Express useful for REST-style APIs and JavaScript backends.
Step 7: Add 404 and Error Handling
A production Express.js web app should handle routes that do not exist and unexpected application errors.
A simple 404 handler can be placed after your routes:
app.use((req, res) => {
res.status(404).json({
error: ‘Route not found’
});
});
Express error-handling middleware uses four parameters:
app.use((err, req, res, next) => {
console.error(err);
res.status(500).json({
error: ‘Internal server error’
});
});
The four parameters are:
(err, req, res, next)
Express’s documentation specifically defines this four-argument signature for error-handling middleware.
A basic complete application can therefore look like this:
const express = require(‘express’);
const app = express();
const port = 3000;
app.use(express.json());
app.get(‘/’, (req, res) => {
res.send(‘Hello from Express.js!’);
});
app.get(‘/api/products’, (req, res) => {
res.json([
{ id: 1, name: ‘Laptop’ },
{ id: 2, name: ‘Keyboard’ }
]);
});
app.use((req, res) => {
res.status(404).json({
error: ‘Route not found’
});
});
app.use((err, req, res, next) => {
console.error(err);
res.status(500).json({
error: ‘Internal server error’
});
});
app.listen(port, () => {
console.log(`Server running at http://localhost:${port}`);
});
You now have a small but functional Node.js Express app with routing, JSON support, 404 handling, and error handling.
Recommended Express.js Project Structure
A single app.js file works well for a beginner project. As the application becomes larger, separating responsibilities makes the code easier to maintain.
A common structure is:
my-express-app/
├── src/
│ ├── routes/
│ │ ├── users.js
│ │ └── products.js
│ ├── controllers/
│ ├── middleware/
│ ├── services/
│ └── app.js
├── tests/
├── .env
├── .gitignore
├── package.json
└── README.md
There is no single mandatory structure for Express applications. The official FAQ explicitly states that Express makes no assumptions about application structure, allowing routes and application-specific logic to be organized according to the project’s needs.
For a small application, however, creating dozens of folders can add unnecessary complexity. Start simple and introduce additional layers when the project actually needs them.
Using the Express Application Generator
If you want to generate a larger project skeleton quickly, Express also provides express-generator.
You can run:
npx express-generator my-express-app
Then:
cd my-express-app
npm install
Start the generated application with:
npm start
The generator can create a project with routing, views, public assets, and other application scaffolding. The current Express documentation recommends using npx to run the generator.
The generator is optional. For a small API or learning project, manually creating the application can make it easier to understand how Express actually works.
Express.js Best Practices
Creating an Express application is straightforward, but production applications need more than basic routes.
Keep these practices in mind:
Use a Supported Node.js Version
Use an actively supported Node.js LTS release for production applications rather than an outdated Node version. Node.js maintains separate Current and LTS release lines.
Keep Dependencies Updated
Regularly review and update Express and other npm dependencies. Security vulnerabilities can exist in direct and transitive dependencies.
Validate Incoming Data
Never assume that request parameters or JSON bodies are trustworthy. Validate input before using it in application logic, database queries, or external services.
Protect Secrets
Do not hardcode database passwords, API keys, tokens, or other secrets in source code. Use appropriate environment or secret-management mechanisms.
Use Security Middleware Where Appropriate
Production applications commonly use security-focused middleware and appropriate HTTP security headers. Configure these according to the application’s deployment architecture rather than blindly copying a configuration.
Separate Routes and Business Logic
As an application grows, use routers, controllers, and services where they genuinely improve maintainability.
Add Automated Tests
Test important routes, authentication flows, validation, error handling, and business logic before deploying significant changes.
Use HTTPS in Production
Local development can use http://localhost, but production applications should normally be deployed behind HTTPS.
FAQs
Is Express.js still relevant?
Yes. Express 5 is the current major Express release and continues to provide a lightweight approach to building Node.js web applications and APIs. Express 5 was officially released in 2024 and remains actively maintained, with security releases published during 2026.
Is Express.js the same as Node.js?
No. Node.js is the JavaScript runtime, while Express.js is a web framework that runs on Node.js and provides abstractions such as routing and middleware.
Which Node.js version is required for Express 5?
Express 5 requires Node.js 18 or higher. For new production projects, use a currently supported Node.js LTS release.
Can Express.js be used to build REST APIs?
Yes. Express provides routing and HTTP request/response handling that can be used to build REST-style APIs and backend services.
Can I use TypeScript with Express.js?
Yes. Express can be used with TypeScript. The official Express documentation provides TypeScript setup guidance using TypeScript together with @types/express and @types/node.
Should beginners use the Express generator?
Not necessarily. Beginners may find it easier to understand Express by creating a small application manually first. The generator is useful when you want a ready-made project skeleton for a larger application.
Conclusion
Learning how to create a web app with Express.js is a practical way to get started with backend JavaScript development.
With Express 5, you can create a Node.js server, define routes, process JSON requests, add middleware, build APIs, and handle errors without introducing unnecessary complexity. Express also gives developers the flexibility to choose their own database, application architecture, template engine, and project structure.
Start with a small application containing a few routes, then introduce routers, controllers, services, authentication, databases, validation, testing, and other components as the project grows.
For modern development, keep Express and npm dependencies updated, use a supported Node.js LTS release, protect application secrets, validate user input, and integrate automated testing and security practices into your development workflow.