Before we dive in, let’s revisit how Typescript and React works together. React is a JavaScript library for building interactive user interfaces, while Typescript is a “typed super-set of JavaScript that compiles to plain JavaScript.” By using them together, we will essentially build our user interfaces using a typed version of JavaScript.

The main reason you might use them together would be to get the benefits of a statically typed language for the user interfaces. Which means more safety and fewer bugs shipping to the front end.

Project GitHub repository


  • React – A JavaScript library for building user interfaces.
  • create-react-app (CRA) –  A tool from Facebook for building modern React applications.
  • Typescript– A typed super-set of JavaScript that compiles to plain JavaScript
  • Redux-Toolkit – The official, opinionated, batteries-included tool set for efficient Redux development.
  • Redux-Injectors – Dynamically load Redux reducers and Redux-saga sagas as needed, instead of loading them all upfront.
  • Redux-Saga – A JavaScript library that aims to make application side effects easier to manage, more efficient to execute, easy to test, and better at handling failures.

Setup CRA with Typescript

Like we did on my previous blog, we’ll first create a Counter app using React, Typescript, Redux-Toolkit, and Redux-Saga. This will act as the boilerplate of our custom template. When configuring a custom Create React App and Typescript template, I find it easiest to bootstrap it with CRA itself.

To start a new Create React App project with Typescript, you can run:

npx create-react-app cra-template-my-app --template typescript

CRA will do its thing (substitute my-app with whatever you want to name your project). You’ll notice that Custom Templates are always named in the format cra-template-[template-name], however, you only need to provide the [template-name] to the creation command. Then cd into the directory to layout the app directory structure.

Here’s what it should look like:

├── cra-template-my-app
       ├── public
       ├── src
       │   ├── counter
       │   ├   ├── index.ts
       │   ├── sagas
       │   ├   ├── index.tsx
       │   ├── App.css
       │   ├── App.tsx
       │   ├── App.test.tsx
       │   ├── Counter.tsx
       │   ├── index.css
       │   ├── index.tsx
       │   ├── logo.svg
       │   ├── react-app-env.d.ts
       │   ├── rootReducer.ts
       │   ├── serviceWorker.ts
       │   ├── setupTests.ts
       │   ├── store.ts
       ├── .gitignore
       ├── package.json
       ├── tsconfig.json

To add Typescript to a Create React App project, first install it:

npm install --save typescript @types/node @types/react @types/react-dom @types/jest

Next, rename any file to be a TypeScript file ( e.g.  src/index.js  to  src/index.tsx ) and restart your development server!

Type errors will show up in the same console as the build one. You’ll have to fix these type errors before you continue development or build your project.

This will get you the bare minimum to start writing React with TypeScript. A few noticeable differences are:

  • the .tsx file extension
  • the tsconfig.json
  • the react-app-env.d.ts

The tsx is for “Typescript JSX”. The tsconfig.json is the Typescript configuration file, which has some defaults set. The react-app-env.d.ts references the types of react-scripts, and helps with things like allowing for SVG imports.

For advanced configuration, see here.

Step 1 – Redux Saga and Store Setup

For this tutorial, we will be using Redux which is an external state management library system. It’s popular and therefore has a lot of support. We will also be using Redux-Toolkit a toolset of batteries for efficient Redux development.

We will install the following:

npm install redux react-redux redux-injectors

npm install --save-dev redux-devtools-extension

Redux-Injector will dynamically load redux reducers and redux-sagas as needed, instead of loading them all upfront. This has some nice benefits, such as avoiding having to manage a big global list of reducers and sagas. It also allows more effective use of code-splitting. 

Store Setup

All the logic related to configuring the store – including importing reducers, middleware, and enhancers – is handled in the src/store.ts file.

To achieve this, configureAppStore function looks like this:

createSlice is a function that accepts an initial state, an object full of reducer functions, and a “slice name”, and automatically generates action creators and action types that correspond to the reducers and state. The app reducer functions will be in the src/counter/index.ts file.

createReducer is a utility that simplifies creating Redux reducer functions, by defining them as lookup tables of functions to handle each action type. It also allows you to drastically simplify immutable update logic, by writing “mutative” code inside your reducers.


Sagas are implemented as Generator Functions that yield objects to the redux-saga middleware. The middleware interprets the yielded objects as instruction. When a Promise is yielded to the middleware, the middleware will suspend the Saga until the Promise completes it. The middleware will suspend the Saga until the yielded Promise completes. In the code below found in src/sagas/index.tsx file, the incrementAsync Saga is suspended until the Promise returned by delay resolves, which will happen after 1 second.

Once the Promise is resolved, the middleware will resume the Saga, executing code until the next yield. The next statement is another yielded object: the result of calling put({type: 'INCREMENT'}), which instructs the middleware to dispatch an INCREMENT action.

put is one example of what we call an Effect. Effects are plain JavaScript objects which contain instructions to be fulfilled by the middleware. When a middleware retrieves an Effect yielded by a Saga, the Saga is paused until the Effect is fulfilled.

So to summarize, the incrementAsync Saga sleeps for 1 second via the call to delay(1000), then dispatches an INCREMENT action.

Next, we created another Saga watchIncrementAsync. We use takeEvery, a helper function provided by redux-saga, to listen for dispatched INCREMENT_ASYNC actions and run incrementAsync each time.

Now we have two Sagas, and we need to start them both at once. To do that, we’ll add a rootSaga that is responsible for starting our other Sagas. The src/sagas/index.tsx file should be as follows:

Step 2 – Bind with React Redux

In the /index.tsx file, we pass the Redux store object to the react-redux Provider component, which is rendered at the top of our component tree.

This ensures that any time we connect to Redux, the store is available to our components.

Step 3 – Create a Counter Component

We need three buttons for the view. An incrementAsync(delay +) button, increment(+) button and a decrement button(-). As we are on React, we will create a Counter component that will contain our button components inside the /Counter.tsx file. Here we are getting the values from the main component(App.tsx) as props.

Step 4 – Setup App.tsx

Inside the /App.tsx file import Counter component we created earlier and update the file to look like the one below.

Update the App.css file to reflect the following:

Now run npm start to test the Counter App by clicking on the increment, increment async and decrement buttons.

Step 5 – Building the Typescript template

In this second part, we will be covering how to convert the Typescript Redux-Saga counter app to a custom template.

A template must have the following structure, so update our app to reflect this:

├── cra-template-my-app
       ├── template
       │   ├── public
       │   ├── src
       │   ├   ├── counter
       │   ├   ├   ├── index.ts
       │   ├   ├── sagas
       │   ├   ├   ├── index.tsx
       │   ├   ├── App.css
       │   ├   ├── App.tsx
       │   ├   ├── App.test.tsx
       │   ├   ├── Counter.tsx
       │   ├   ├── index.css
       │   ├   ├── index.tsx
       │   ├   ├── logo.svg
       │   ├   ├── react-app-env.d.ts
       │   ├   ├── rootReducer.ts
       │   ├   ├── serviceWorker.ts
       │   ├   ├── setupTests.ts
       │   ├   ├── store.ts
       │   ├── gitignore
       │   ├──
       │   ├── tsconfig.json
       ├── package.json
       ├── template.json

The template folder

The folder will be copied to the user’s app directory when Create React App installs. During this process, the file gitignore is renamed to .gitignore.

You can add whatever files you want in here, but you must have at least the files specified above.

The template.json file

This is the configuration file for your template. As this is a new feature, more options will be added over time. For now, only a package key is supported.

The package key lets you provide any keys/values that you want to be added to the new project’s package.json, such as dependencies (only dependencies are supported for now) and any custom scripts that your template relies on.

Below are the contents of our template.json file:

Step 6 – Testing a template

Create React App can use a local template on your file system. This is useful for development, or if you don’t want to publish. To test a template locally, pass the file path to the directory of your template root using the file: prefix.

Use npx create-react-app my-app --template file:. in your template root folder.

npx create-react-app my-app --template file:../path/to/your/template/cra-template-saga

Step 7 – Publishing a template on npm

Publishing to npm is a topic of its own. To keep the scope small: After registering at npm and authorizing on the CLI

npm login

Run the following command to publish the project as an npm package:
npm publish --access public

Wow, congratulations, you should now have created and published a Create React App custom template. Bootstrap a new React application with npx create-react-app your-app --template your-custom-template.

The published npm package

Learning Tools

There is a lot that we can gain from Typescript when using it to type check. Find below useful links to learn more about Typescript, React, Redux-Toolkit, Redux Injectors, Create React App, and Redux Sagas.

Learning Strategy

To get the most out of this article and the GitHub project, you will need to have basic knowledge of how Typescript works as a super-set of JavaScript in a React app. You also need to understand how redux-saga a Redux middle ware handles React applications side effects. Armed with that knowledge, I believe you can be able to apply what you have learned here when working with client-facing applications built with Typescript and React.

Reflective Analysis.

As the code base of a React app grows, it can become too difficult to read, share, or maintain. Navigating these code bases can be tedious, and refactoring code is risky. Typescript helps you refactor code and prevent typos, making it far easier to maintain and update without changing any of its behaviors. Also one of the most loved features of Typescript is its ability to highlight errors as soon as they crop up. Typescript shows you errors before you ever run the code, saving hours of time fixing bugs or mistakes early on.


This was a very basic intro to Typescript majorly focusing on how to setup Typescript using CRA(Create React App) which should enable anyone to start with Typescript.

You can always refer to the GitHub repository to clone the project we have created.

Please share your thoughts about this article in the comment section, I’d be happy to talk! Thanks for reading, learning and sharing.

More on React and Redux, checkout out this: How to create a Custom Redux-Saga Template with CRA