Our First Express Code and Route

Now that we understand some key concepts, let us build and run our first Express server together. We will walk through each part of the code and explain what it does, as well as how to run and test our server.

Write Our First Express Server

Add the following code to src/index.ts:

import express from "express";

const app = express(); // This creates our Express application
const PORT = 3000; // This is the port our server will listen on

// This defines a GET route for the root URL ('/')
app.get("/", (req, res) => {
  // req (the request) contains information about the incoming request (URL, query params, etc.)
  // res (the response) is used to send data back to the client
  res.json({ message: "Hello world!" }); // This sends a JSON response to the client
});

// This starts the server and listens for incoming requests
app.listen(PORT, () => {
  console.log(`Server running at http://localhost:${PORT}`);
});

What does each part do?

  • express(): Creates our Express application. This is the main object we use to define routes and handle requests.
  • app.get('/', ...): Sets up a route that listens for GET requests to the root URL (/).
  • (req, res): Every route handler receives two arguments:
    • req (the request): Contains information about the incoming request (such as URL, query parameters, headers, etc.).
    • res (the response): Used to send data back to the client, usually with methods like res.json().
  • res.json({ message: 'Hello world!' }): Sends a JSON response back to the client. This is the standard way to return data from an API endpoint.
  • app.listen(PORT, ...): Starts our server and tells it to listen for requests on the specified port. The callback function runs when the server starts.
  • console.log(...): Prints a message to the terminal where we started the server. This is not visible in the browser’s console — unlike frontend development, all console.log output from our backend code appears in our terminal or command prompt.

Testing your API endpoint

  • The res.json method sends JSON data from our server to the client that made the request. After we start the server, if we visit http://localhost:3000/ in a browser, we will see a JSON response: { "message": "Hello world!" }. If we use Postman or curl, the same JSON will be returned in the response.

Why use res.json?

  • res.json is the standard way to send data from an API. It ensures the response is always in JSON format, which is what frontend applications expect when working with APIs.

Running Our Server

There are a couple of ways to run our TypeScript server:

  • tsx is a tool we installed above that runs our TypeScript code directly and automatically restarts the server when we make changes. This is very convenient during development and works perfectly with ES modules.
  • To run the server with tsx, use:

    npx tsx watch src/index.ts
    
  • Now, whenever we save changes to our code, the server will restart automatically. Visit http://localhost:3000/ to see the json returned. Change the value in res.json to see the return value updated without restarting the server.

Option 2: Using tsc and node (For Production)

  • We can also compile our TypeScript code to JavaScript and then run it with Node.js.
  • First, compile the code:
    npx tsc
    
  • Then, run the compiled code:

    node dist/index.js
    

    This output is compiled into the dist folder and will need to be compiled again before you see any changes. So use this for production, not for development.

Setting Up Scripts in package.json

To make running our server easier, let us add scripts to our package.json file:

"scripts": {
  "dev": "tsx watch src/index.ts",
  "build": "tsc",
  "start": "node dist/index.js"
}
  • npm run dev: Starts the server in development mode with auto-reloading.
  • npm run build: Compiles our TypeScript code to JavaScript.
  • npm start: Runs the compiled JavaScript code (for production).


Repo link

Tags: