This is an introduction to Node.js that is a server to run JavaScript applications. After a brief history of this tools, I will create a simple web application.
The source code of this post is available on GitHub. This is part of my MSc at Birkbeck University.
What is Node.js?
Node.js has long been a staple for server-side programming, offering a JavaScript runtime that enables developers to build scalable network applications. In the latest release, Node.js 21, the platform takes a significant leap forward, introducing updates and features that promise to enhance performance, security, and developer experience.
What’s new in the latest version
One of the most notable changes in Node.js 21 is the update of the V8 JavaScript engine to version 11.8. This update brings improved performance and new language features, such as Array grouping and ArrayBuffer.prototype.transfer, which developers can leverage to write more efficient code.
Another exciting development is the stabilization of fetch and WebStreams. These features have been marked stable, indicating their readiness for production use. Fetch provides a straightforward way to make web requests, while WebStreams allows handling streaming data, such as video or audio, with ease.
Node.js 21 also introduces an experimental flag –experimental-default-type, which allows developers to flip the default module system used by Node.js. This feature is particularly useful for those who are transitioning from CommonJS to ES modules, as it provides a more flexible way to manage module types.
The built-in WebSocket client is another addition that catches the eye. Although still experimental, it offers a browser-compatible WebSocket implementation, enabling real-time communication capabilities for web applications.
For those involved in testing, support for globs in the Node.js test runner is a welcome enhancement. It simplifies the process of running tests by allowing the use of glob patterns, making it easier to execute tests across multiple files and directories.
Updating to Node.js 21 is straightforward, and developers are encouraged to adopt the new version to take advantage of these improvements. The update process typically involves clearing the NPM cache, installing the new version, and, if necessary, pruning previous versions to maintain a clean development environment.
As Node.js continues to evolve, it remains committed to providing a robust and versatile platform for server-side development. Node.js 21 is a testament to this commitment, offering a range of features that cater to the needs of modern web development.
For developers
For developers looking to stay ahead of the curve, embracing Node.js 21 is a step towards building more performant, secure, and efficient web applications. The future of server-side JavaScript looks bright, and Node.js is at the forefront of this exciting journey.
To download Node.js 21 and explore the full list of features and updates, visit the official Node.js website. Embrace the future of server-side JavaScript with Node.js 21 and unlock the full potential of your web applications.
Install Node.js
The first step is to install on our computer Node.js. You can download it from the official website. After the installation, you can use tools like npm
and run your server for your application.
If you don’t have Visual Studio Code, download it from the official website and then you will be ready to start.
First web application
Now, open Visual Studio Code and open a folder from the menu where you add all the files for the first application.
First, I have to initialize my Node.js application and for that, I have to open the Terminal from Visual Studio Code.
Next, in the Terminal window, I have to type the command to initialize the Node.js application: the initialization downloads for us all the required packages. I have to use NPM (Node Package Manager) and the command is
npm init
This command prepares for me the basic configuration of a Nade.js project. Press Enter to choose the default values during the initialization like in the following screenshot.
The result is a json file called package.json
with all the details of my application.
{
"name": "00-install",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"description": ""
}
In Visual Studio Code, I can see there is a gray text for Debug. I don’t think it is doing nothing now, but I like to press it and see what it happens.
Now, I want to install a package called Express which is a small package provided by Node.js to create a simple and fast server.
npm install express
Then, I want to install another package called nodemon that helps me to restart my server every thing I change my code.
npm install nodemon
The next step is to change the configuration to use nodemon to run the application. For that, in the package.json
, remove the line started with test
and replace with this one
"start": "nodemon app.js"
By convention, all the Node.js applications start from an app.js
file.
The first app.js
Now, add in your folder a file called app.js
. The first thing is to add the library express
that helps us to have routes and other component in the app. This library is required.
const express = require('express')
Then, I have to create the application. For that, I type
const app = express()
So, I can create routes. Routing refers to how an application’s endpoints (URIs) respond to client requests. For an introduction to routing, see Basic routing.
You define routing using methods of the Express app
object that correspond to HTTP methods; for example, app.get()
to handle GET requests and app.post
to handle POST requests. For a full list, see app.METHOD. You can also use app.all() to handle all HTTP methods and app.use() to specify middleware as the callback function (See Using middleware for details).
These routing methods specify a callback function (sometimes called “handler functions”) called when the application receives a request to the specified route (endpoint) and HTTP method. In other words, the application “listens” for requests that match the specified route(s) and method(s), and when it detects a match, it calls the specified callback function.
First GET
When we type in the browser a URL, this is a GET call to the server. Every call has a request and a response. So, I have to define a simple response to the request to the server as the home page. Add this code:
app.get('/', (req, res) => {
res.send('Hello!');
})
Explanation
I created a variable for the application called app
. To the app
, I add a GET request to the home page or root of the web application and this is the '/'
in the first part of the definition of the GET
. Then, this function requires a response and a result variables that we can use in our code: req
and res
are the 2 variables I defined in the core above.
The variable res
has properties and methods that I can use to send output or read input. In this example, I want to print Hello!
Create the server
Now, I have to tell Node.js on what port the application has to use to respond to the calls. Generally speaking, a website responds on the port 80
(HTTP) or 443 (HTTPS) but those ports can change. As a convention, I use the port 3000 for Node.js applications.
app.listen(3000, () => {
console.log('Server is up and running')
})
When the application starts, I want to print in the logs a sentence – in this case Server is up and running – for debug purposes. Because I run the application on my local machine, I open the web application using this URL
http://localhost:3000/
localhost
is a conventional name to use in URLs to identify my local machine and this is an alias of the 127.0.0.1
IP that identifies my local machine.
Debug time
Now, I can tell Visual Studio Code that I want to debug this application and try it in a browser. For that, click on the Run and Debug on the menu on the left, select the URL
Now, every time I run the application, I can see the result and if there is an error, I will be redirect to the line when the error occurs.
Instead of using Visual Studio Code feature to run your code, you can type in the Terminal
npm start
and the application will start and then you can point your browse to the address http://localhost:3000
.
Add a new route
Just for fun, I add another route in the application adding this code
app.get('/movies', (req, res) => {
res.send('You are in the movies page')
})
If I run the application, I can see the home page but also I can go to
http://localhost:3000/movies
Route folder
Now, to keep your application easy to read and understand, a common action to do is to have different folders where to add the files for each section of the application. For this reason, create a new folder called routes
.
The route for movies
Now, I create a file called movies.js
that is another express
application. Because this is a new route, I have to define that for Node.js and so, I have to write those lines
const express = require('express')
const router = express.Router()
In order to let Node.js knows that I want to use the routes in this file, I have to export the routes with there definitions. So, I added at the end of the file this line
module.exports = router
Adding this route means that Node.js recognizes an URL like http://localhost:3000/movies
Then, I can add the routes I like and also I can define different routes in this file. For example, adding those lines
router.get('/', (req, res) => {
res.send('You are in movies (router)')
})
allows us to open the URL http://localhost:3000/movies
because this code defines the root of the route movies
. If I want to add another sub URL, for example http://localhost:3000/movies/starwars
, I have to write another router like
router.get('/starwars', (req, res) => {
res.send('Star Wars!')
})
Add the route to the application
Now, define the route and the router is not enough for the application to know where to do. So, I have to add this route to the main application. So, in the app.js
I have to tell that I want to use the file movies.js and that I want to map the routes in this file with the route movies
. Here the code:
const movieRoute = require('./routes/movies')
// Middleware
app.use('/movies', movieRoute)
We call middleware this implementation of the routes. Now, we can play with the application.
Wrap up
I hope this is a good and simple introduction to Node.js. Remember, you have all the source code in GitHub.