Express Quickstart Tutorial
All you need to know about getting started quickly with Express!
About Express
Express is a web framework for the Node.js runtime. If you haven't installed Node.js yet, please refer to this side dish.
Let's get a little more detailed: Express is a relatively lightweight and straightforward approach to writing your web application's back-end, or server-side. Core concepts to working with a framework like this include the following.
Important Terms
- HTTP Web Server: HTTP is a protocol and standard used for traffic over the internet. It is this protocol that you use in order to request and download world wide web pages to your web browser! A server that is able to accept HTTP requests, and send HTTP responses is a web server.
- Request-Response Communication: When working with web servers, it is important to make note of the communication style in play. We mentioned the server, above, but it is also important to acknowledge the web client. The software and device that makes requests is the client—in most of your day-to-day this will mean a web browser like Firefox. This application makes requests, and acts as a client. Another computer has different software running, and will be listening for client requests. It is that computer and software that are referred to as the web server.
- Back-End: We can think of a world wide web site's back-end as the code that runs on the web server. Technologies like Node.js, Express, and EJS are considered back-end, or server-side.
- Front-End: We can think of a world wide web site's front-end as the code that runs on the web client. Languages like HTML, CSS, and JS are considered front-end, or client-side. Note that if JavaScript is run using Node.js, it is considered server-side, and if it is run in the web browser it is considered client-side—this distinction can be confusing until you've had some practice!
- Framework: A series of classes, functions, and/or variables along with conventions for more quickly and reliably writing an application. A framework is a way to save time, more quickly get started with a team, and at times a more reliable and battle-tested approach to tackling projects and tasks.
- Templating Languages and Engines: It can be tricky to perfectly format characters, text, and strings for output. On the web, we often want to prepare HTML as our target output format, and this can be annoying following string syntaxes. Template languages are designed to provide an easier way to prepare and format output that a client (like a web browser) can understand.
Basic Set-up
Express' official world wide web site can be found here if you'd like more information, but I'll break down the basics. First thing to make note of is that Express can be easily downloaded into your project via its npm package, here. To take advantage of this, make sure you have Node.js installed, it will come with the npm Node package manager.
- Create a directory (folder) on your computer for your project. Name the directory what you'd like, I'll use my-express-app as the placeholder name for this example. You can do this via your file manager or Finder if you'd like, or you can do so using the terminal:
# Navigate to your user directory
cd ~
# Enter your projects directory, if you have one
cd projects
# Create a new directory for this project
mkdir my-express-app
# Don't forget to enter the new project directory!
cd my-express-app
- In-order to use the Express package, we should set-up npm for this project. We'll first create a package.json file, which will keep track of any packages we'll use in this project:
# Create your package.json file quickly with this:
npm init -y
or
# Run without the "-y" to customize your project's package.json instead:
npm init
- Now that there is a package.json, we'll install Express. All we need to do is run this line, and we'll be good to start building our application!
npm install express --save
- Now we'll create a file in our project directory, it is here that our application code will live. I'll call mine index.js, but feel free to name yours what you'd like! See the following code, taking time to read the comments:
/**
* index.js
* My first Express application!
* @link https://digital-diner.io/mains/2024-06-24-getting-started-with-express.php
*/
// This will load the express package into our file!
const express = require('express');
// We'll run the 'express' function and store the result in a variable: 'app'
const app = express();
// Choose a network port, we'll use this later to connect to our application from the browser!
const PORT = 3333;
// Tell your Express application to listen for requests (from any client, but usually a web browser.)
app.listen(PORT, function() {
console.log('Express is now listening here:');
console.log(`http://localhost:${PORT}`);
});
- This will be enough for us to run the server, though it won't do a lot just yet. If you want to run it to see if there are any errors, run the following command in your terminal:
# Use node to run your project file:
node index.js
Make note of the PORT you chose in your code above. If you used 3333, for example, you should be able to visit your application via http://localhost:3333 while your program is running. If everything is working you shouldn't see any errors in your terminal, and visiting that link should display "Cannot GET /". This might sound bad, but this is because we haven't written any code telling the server what to send to the browser. Express is being kind enough to let us know this!
Basic Routing
There are a few terms you'll want to acquaint yourself with before jumping into this next set of steps.
Important Terms
- Path: On a computer this usually refers to the "location" of something. How would you get to a specific directory or file from the root of your system? When visiting web pages, you'll find a similar pattern in your address bar. You'll often find what looks like directories and/or file names after the domain name. For example, look at the address for the page you're on right now: https://digital-diner.io/mains/2024-06-24-getting-started-with-express.php. The path in this address would be: /mains/2024-06-24-getting-started-with-express.php.
- Method: Each request made by a web client will have a path, but it will also have a method. This describes the type of request being made. The most common method is GET. In-fact, the request your web browser made to view this very page was a GET request! Let's explore the main difference(s) between GET, and the other method: POST.
- GET Method: A GET method request is largely focused on asking for a specific resource, or output, from the server. Most important information about the request is included in the path, or address, in this case. GET requests are often repeatable, bookmarkable, and easy to copy & share with others. For example, the page you're viewing right now! You could easily bookmark this page, or share the link with a friend, and they'd get the same result. Even some web forms are used to create a GET request. Consider your favourite search engine—even the submitted search could be easily repeated, bookmarked, or shared. For example: https://duckduckgo.com/?q=Digital-Diner.io. You'll notice that any information about the search is simply included in the address.
- POST Method: A POST method request is largely focused on sending additional data outside of the address. This type of request can contain a body, and marking a request as a POST will allow you to include this body of data or content along with your request. This is not the default type of request, so it is usually handled by certain web form submissions or sometimes even by client-side (web browser) JavaScript called Ajax. This is commonly used in cases where you might not want to see the data in the address or have it easily sharable—consider a sign-in form for example! You wouldn't want to see your password up in the address bar, or be able to send your sign-in details in a link. Another common example would be a "create" or "edit" form, like you might find on X (formerly Twitter) or Facebook when working on a post. You don't want to accidentally create copies of posts, so that action shouldn't be easily repeated, bookmarked, or shared.
- Route: When building a web application the term route refers to a combination of method and path available on the server. If a client asks for that specific method and path combination, the server can be programmed to perform any required logic and/or send a specific response (usually an HTML web page.) Consider the last time you visited your favourite world wide web site. Watch the address bar at the top of your web browser, you're likely visiting many different paths as you navigate the site—each of these requests provides your browser with a new HTML web page as a response. Pretty nifty, eh?
Your First Route
The easiest for us to get started with will be a GET route. We'll need to ensure that each route has either a unique method or path. Let's update our index.js file that we had created earlier:
/**
* index.js
* My first Express application!
* @link https://digital-diner.io/mains/2024-06-24-getting-started-with-express.php
*/
// This will load the express package into our file!
const express = require('express');
// We'll run the 'express' function and store the result in a variable: 'app'
const app = express();
// Choose a network port, we'll use this later to connect to our application from the browser!
const PORT = 3333;
// Tell your Express application to listen for requests (from any client, but usually a web browser.)
app.listen(PORT, function() {
console.log('Express is now listening here:');
console.log(`http://localhost:${PORT}`);
});
/**
* Our very first route!
* Notice that the '.get' signifies that the server will list for GET requests
* 1) The first argument for '.get' is the path! Let's try: '/hello-world'
* 2) The second argument for '.get' is a function! This will run when someone visits our route.
*/
app.get('/hello-world', function(request, response) {
// We'll just send a basic HTML string that says 'Hello, World' to the client:
response.end('<h1>Hello, World!</h1>');
});
As per the comments in the snippet, we're using the app.get method afforded to us by Express. This means the web application will listen for a matching GET request. This method requires two arguments:
- Path: The part of the address after the domain name.
- Function: If a client (web browser) requests the method and path specified, together, this function will run! It is your opportunity to have any necessary logic run, and typically, send some kind of output or message to the client.
To run the above example, use your terminal again. If you still have the example running from before, you'll want to stop it (use CTRL + C to end the process) and start it again.
# Run the web application again:
node index.js
Because response.end tells our Express server to send a response back to a client that has sent a request, visiting http://localhost:3333/hello-world will display "Hello, World!" in a web page now!
A Better Route
Our GET /hello-world page works! But it isn't really a valid HTML web page. We're missing a bit of code. The focus of this article isn't really the nitty-gritty of HTML, but let's make a route that at-least follows the rules properly. Update your index.js again with the following, new, GET /about route:
/**
* index.js
* My first Express application!
* @link https://digital-diner.io/mains/2024-06-24-getting-started-with-express.php
*/
// This will load the express package into our file!
const express = require('express');
// We'll run the 'express' function and store the result in a variable: 'app'
const app = express();
// Choose a network port, we'll use this later to connect to our application from the browser!
const PORT = 3333;
// Tell your Express application to listen for requests (from any client, but usually a web browser.)
app.listen(PORT, function() {
console.log('Express is now listening here:');
console.log(`http://localhost:${PORT}`);
});
/**
* Our very first route!
* Notice that the '.get' signifies that the server will list for GET requests
* 1) The first argument for '.get' is the path! Let's try: '/hello-world'
* 2) The second argument for '.get' is a function! This will run when someone visits our route.
*/
app.get('/hello-world', function(request, response) {
// We'll just send a basic HTML string that says 'Hello, World' to the client:
response.end('<h1>Hello, World!</h1>');
});
/**
* All about our project!
* Notice that this route uses the same method as our last one, but has a different path!
*/
app.get('/about', function(request, response) {
response.end(`<!DOCTYPE html>
<html>
<head><title>About</title></head>
<body>
<h1>About</h1>
<p>This is a practice world wide web site built using Express as the back-end. This <em>GET /about</em> page uses valid HTML, unlike our <em>GET /hello-world</em> page.</p>
</body>
</html>`);
});
This response.end string is far more complete, and will be appreciated more by web browsers and search engines.
Templates with EJS
You could continue to write routes and output like we have done above, and it would work A-okay! However, most web developers would prefer to organize the "output" in a file or template separate from this "logic" file that we've been working in. This is generally considered to be a good practice, and is called separation of concerns—the idea that there should be a time and a place for code with specific responsibilities. Effectively the ask is that you make an effort to stay organized!
One common way to go about this for your HTML output in an Express application is to incorporate a template language or template engine like EJS: "Embedded JavaScript." While EJS is not exclusive to Express (it can be used on its own, with web application libraries, or even with other frameworks) it works very well with it—so we'll use this template language in our example.
By this point in this tutorial, we've already installed npm Node packages, so installing another (EJS) will be easy. You can find the official world wide web site here, and the official npm web page here. Install it to your current project via the following command in your terminal:
npm install ejs --save
Now, we'll ask ourselves where these EJS template files will end up living. By default, EJS and Express will expect your template files to be placed in the project's views directory. Right now, we have not created one... though, this can be easily remedied in your terminal:
mkdir views
Presto! Now we have a place for any templates we create. We do have to adjust our index.js file, adding a new line to let Express know we'd like to enable EJS template support:
/**
* index.js
* My first Express application!
* @link https://digital-diner.io/mains/2024-06-24-getting-started-with-express.php
*/
// This will load the express package into our file!
const express = require('express');
// We'll run the 'express' function and store the result in a variable: 'app'
const app = express();
// Choose a network port, we'll use this later to connect to our application from the browser!
const PORT = 3333;
/**
* Activate template support! 🆕
*/
app.set('view engine', 'ejs');
// Tell your Express application to listen for requests (from any client, but usually a web browser.)
app.listen(PORT, function() {
console.log('Express is now listening here:');
console.log(`http://localhost:${PORT}`);
});
/**
* Our very first route!
* Notice that the '.get' signifies that the server will list for GET requests
* 1) The first argument for '.get' is the path! Let's try: '/hello-world'
* 2) The second argument for '.get' is a function! This will run when someone visits our route.
*/
app.get('/hello-world', function(request, response) {
// We'll just send a basic HTML string that says 'Hello, World' to the client:
response.end('<h1>Hello, World!</h1>');
});
/**
* All about our project!
* Notice that this route uses the same method as our last one, but has a different path!
*/
app.get('/about', function(request, response) {
response.end(`<!DOCTYPE html>
<html>
<head><title>About</title></head>
<body>
<h1>About</h1>
<p>This is a practice world wide web site built using Express as the back-end. This <em>GET /about</em> page uses valid HTML, unlike our <em>GET /hello-world</em> page.</p>
</body>
</html>`);
});
Let's make one now. Make a new file called index.ejs, and place it inside of your new views directory. As far as your project is concerned, we can think of this as living at views/index.ejs. Write the following HTML code in your template file:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My Express App</title>
</head>
<body>
<h1>My Express App</h1>
<p>Welcome to my Express application!</p>
<nav>
<h2>Other Pages:</h2>
<ul>
<li>
<a href="/hello-world">http://localhost:3333/hello-world</a>
</li>
<li>
<a href="/about">http://localhost:3333/about</a>
</li>
<li>
<a href="/">Home</a>
</li>
</ul>
</nav>
</body>
</html>
Now, it is important to note, that this template is not yet associated with any route. Unless our application has logic to display a template, it will not be viewable via a web browser. So our next step? Build a route, and program it to display this new page of ours!
We'll have to make another addition to our index.js file, letting it know to use that new template:
/**
* index.js
* My first Express application!
* @link https://digital-diner.io/mains/2024-06-24-getting-started-with-express.php
*/
// This will load the express package into our file!
const express = require('express');
// We'll run the 'express' function and store the result in a variable: 'app'
const app = express();
// Choose a network port, we'll use this later to connect to our application from the browser!
const PORT = 3333;
/**
* Activate template support!
*/
app.set('view engine', 'ejs');
// Tell your Express application to listen for requests (from any client, but usually a web browser.)
app.listen(PORT, function() {
console.log('Express is now listening here:');
console.log(`http://localhost:${PORT}`);
});
/**
* Our very first route!
* Notice that the '.get' signifies that the server will list for GET requests
* 1) The first argument for '.get' is the path! Let's try: '/hello-world'
* 2) The second argument for '.get' is a function! This will run when someone visits our route.
*/
app.get('/hello-world', function(request, response) {
// We'll just send a basic HTML string that says 'Hello, World' to the client:
response.end('<h1>Hello, World!</h1>');
});
/**
* All about our project!
* Notice that this route uses the same method as our last one, but has a different path!
*/
app.get('/about', function(request, response) {
response.end(`<!DOCTYPE html>
<html>
<head><title>About</title></head>
<body>
<h1>About</h1>
<p>This is a practice world wide web site built using Express as the back-end. This <em>GET /about</em> page uses valid HTML, unlike our <em>GET /hello-world</em> page.</p>
</body>
</html>`);
});
/**
* Our home page!
* This route uses a template, which generally viewed as a better practice—it follows the idea: "separation of concerns."
*/
app.get('/', function(request, response) {
// Note that we just say the name of the template file!
// It looks in the /views directory for a file with this name (you don't need to mention the '.ejs'.)
response.render('index'); // Will output based on template at: /views/index.ejs
});
If all steps above have been carried out correctly, using the response.render our browser should now receive the correct HTML output when we visit http://localhost:3333/.
Want to learn more about using EJS in Express? Take your knowledge to the next level with this main course, all about EJS and Express!