No Time Dad

A blog about web development written by a busy dad

Building a Simple Express Typescript Server

This is a short example on building a simple express typescript server. It doesn’t do much, just returning a small JSON object, and it isn’t production ready code by any stretch, but it’s a great starting point. That’s the point too. Take this example and run with it.

TypeScript is wonderful. I try to use it whenever possible. It makes the code I write much more robust, and dare I say that I feel like I can rely less on unittests. Shocking, I know. But I do really feel that thoroughly typed code can be just as good as tests. I can tell how new someone is to TypeScript by the amount of any definitions in their code. It’s a dead giveaway.

Starting the project

nottimedad@ubuntu:~/workspace/express-ts$ node -v
v14.15.0
mkdir express-ts && cd express-ts
npm init -y
npm install express
npm install typescript @types/node @types/express --save-dev
./node_modules/typescript/bin/tsc --init
touch index.ts

The first thing I’ll do before creating our express typescript server is to create a new project directory. For this example I’m calling it express-ts. This is done via the mkdir express-ts && cd express-ts command, which also changes my current directory to the newly created project directory.

After that, I can initialize a new package.json file via npm init -y. This handy command will create the bare-bones file in our project root. I’m going to make two small changes to this file later, but for now it’ll stay as-is.

Once I have a package.json file I can install the dependencies. The first one I’ll install will be express. After running the install command, npm will update my package.json’s dependencies block to include that package. Next, I’ll install the devDependencies. This is mostly done the same as express was installed, but this time I’ll include the --save-dev flag so npm knows to put these dependencies in the devDependencies block of the package.json file. All packages in this block will not be included in a production build of the project. They’re for development purposes only.

Next, I’ll use the typescript package I just installed to create a tsconfig.json file. I like running this command from the node_modules directory because it doesn’t require me to have the TypeScript compiler (tsc) installed globally (although, I usually do anyways). The tsconfig.json is mostly commented out except for a few lines. I’ll leave this file as-is for this example. Generally speaking, in real projects there are changes I’d go back and make in that file. Particularly for the outDir and target.

The next step is to create an index.ts file. This file is our main entrypoint file for our express typescript server, and where I’ll initialize the express application and define the endpoint endpoints.

The final step in setting up this project is to define how I want to build and start the server. This is done by adding build and start commands to the package.json script section. For this example, “building” the server is really just transpiling the TypeScript to JavaScript. This is done via ./node_modules/typescript/bin/tsc --project ./. Once the code is transpiled, I’ll have a new file in my project root called index.js. I can run it with node using node index.js.

Below is how my sciprts section in package.json should look:

// package.json
"scripts": {
  "test": "echo \"Error: no test specified\" && exit 1",
  "build": "./node_modules/typescript/bin/tsc --project ./",
  "start": "node index.js"
},

Now that the initial setup is done for the express typescript server, I can create the application and endpoints.

import express, { Request, Response } from 'express';

const app = express();
const port = 3005;

app.get('/', (req: Request, res: Response) => {
  res.json({ success: true });
});

app.listen(port, () => {
  console.log(`Application is running on port ${port}`)
});

The first thing I’ll do is define the express application as app. I can then use that definition to start creating endpoints. The first of which will be a get request to the root path (127.0.0.1 or localhost), which’ll return a generic success object that I’ve defined. In most cases, the return object will be much more complex and likely interact with a database.

Once I have the endpoint defined, I can start the server. This is done via app.listen with the port variable I’ve defined. It isn’t required to log a message when the server starts, but I find it helpful to know that it started without issues. Now I can build and run the server.

npm run build && npm run start

The terminal where the command was ran should show something like the below:

> express-ts@1.0.0 start /home/notimedad/workspace/express-ts
> node index.js

Application is running on port 3005

I can then switch over to my browser and visit http://127.0.0.1:3005/, which will display the json response object I defined in index.ts

{ success: true }

Conclusion and final code

Well, that was suprisingly more work than I expected for a simple express typescript server. But, as I mentioned earlier, it’s a great place to start. Or just a way to get a feel for building out an express application.

// express-ts/package.json
{
  "name": "express-ts",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "./node_modules/typescript/bin/tsc --project ./",
    "start": "node index.js"
  },
  "keywords": [],
  "author": "notimedad",
  "license": "ISC",
  "dependencies": {
    "express": "^4.17.1"
  },
  "devDependencies": {
    "@types/express": "^4.17.13",
    "@types/node": "^16.7.2",
    "typescript": "^4.4.2"
  }
}
// express-ts/tsconfig.json
{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "skipLibCheck": true
  }
}
// express-ts/index.ts
import express, { Request, Response } from 'express';

const app = express();
const port = 3005;

app.get('/', (req: Request, res: Response) => {
  res.json({ success: true });
});

app.listen(port, () => {
  console.log(`Application is running on port ${port}`)
});