React and Express.js with Typescript

Create a React and Express js project with TypeScript.

Hello 👋🏼, let's build a React TypeScript log-in form and serve it from an Express TypeScript server. We're not going to focus on how to build a log-in system; instead, we're going to work on the TypeScript and server integration. When we finish, we'll upload the app to Heroku.
Let's start!

1. Set Up Your Node Environment.

  • Make a new directory on your computer and go to that directory.
Terminal
mkdir simple-react-form cd simple-react-form
  • Create a Node js project, use the -y flag to create it without asking questions, and open the project in your code editor. Go to package.json and fill in the empty values.
Terminal
npm init -y code .

2. Set Up Express js and TypeScript.

Install cors, dotenv and express.js. Cors will enable cross-origin requests from outside of our express server port. Dotenv will let us use environmental variables.

Install through npm or yarn
npm install cors dotenv express

Next, install all the libraries related to TypeScript with the -D (development) flag. The concurrently library will let us run multiple commands in package.json scripts. The nodemon library will automatically restart the server when we make changes to any file in the directory.


  npm install -D typescript @types/cors @types/express @types/node concurrently nodemon
  
  • Create the TypeScript configuration file with the following command.
Config
npx tsc --init
  • In the tsconfig.json file uncomment and add these JSON values.
tsconfig.json
{ "compilerOptions": { "target": "es2016", "jsx": "preserve", "module": "commonjs", "allowJs": true, "outDir": "./dist", "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "strict": true, "skipLibCheck": true }, "exclude": [ "client", "dist", "node_modules" ] }
  • Next, go to package.json and update the scripts section.
package.json
{ "scripts": { "build": "npx tsc", "start": "node dist/index.js", "dev": "concurrently \"npx tsc --watch\" \"nodemon -q dist/index.js\"", "test": "echo \"Error: no test specified\" && exit 1" }, }
  • Create index.ts in the root of the project and insert the next code.
index.ts
import dotenv from "dotenv"; import express, { Express, Request, Response } from "express"; import path from "path"; import cors from "cors"; dotenv.config(); const app: Express = express(); app.use(express.json()); app.use(cors()); app.get('/', (req: Request, res: Response) => { res.send('

Hello World From the Typescript Server!

') }); const port = process.env.PORT || 8000; app.listen(port, () => { console.log(`Example app listening on port ${port}`) });
  • Restart your editor if you're using VS Code, open your terminal again and run:
Terminal
npm run build npm run dev
  • You should see this 👇 in your browser.

Chrome Browser

Project File Structure

3. Set Up React and TypeScript.

Now it's time to build our React client-side. First, open your command terminal, ensure you're in the project's root, and install React with TypeScript as a client folder.

Terminal
npx create-react-app client --template typescript
  • Remove the git folder that Reacts installs by default.
Git Bash
cd client rm -rf .git
  • Go to the src folder and create two folders: components and utils.
Git Bash
cd src mkdir components mkdir utils
  • Inside the components folder create another folder called form-input, then, create form-input.tsx and copy the code from below; this file will hold our reusable form inputs. If you want to manipulate the style of the input, create form-input.css in the form input folder.
Git Bash
cd components mkdir form-input cd form-input touch form-input.tsx
client/src/components/form-input/form-input.tsx
  • Go to the utils folder and add data-utils.ts; this file will make the API calls to the server.
client/src/utils/data-utils.ts
  • Modify App.tsx; we're building the login form using the same classes and colors from React.
client/src/App.tsx

4. Add new routes and TypeScript to the server.

We're almost finishing. Go back to index.ts, and add the login route with additional types.

index.ts
interface FormInputs { email: string, password: string } // Array of example users for testing purposes const users = [ { id: 1, name: 'Maria Doe', email: 'maria@example.com', password: 'maria123' }, { id: 2, name: 'Juan Doe', email: 'juan@example.com', password: 'juan123' } ]; // route login app.post('/login', (req: Request, res: Response) => { const { email, password }:FormInputs = req.body; const user = users.find(user => { return user.email === email && user.password === password }); if (!user) { return res.status(404).send('User Not Found!') } return res.status(200).json(user) });
  • Run both the client and the server in individual terminals.
Terminal
npm run dev cd client npm start

Sign-in Form

Client Side File Structure

Check the second part of this tutorial, How to Upload a React and Express TypeScript project to Heroku.