typescript and create-react-app .env
Tags: react, typescript, programming, webdev
Published: 2019-08-06 14:50:43

---
title: typescript and create-react-app .env
published: true
description: Tips on working with CRA environment variables
tags: react, typescript, programming, webdev
---

You can create a type definition file that extends the NodeJS namespace to enable auto-completion for your env configuration. This is quite useful if you plan to reduce the amount of time spent looking up your `.env` file:

![Auto Completion for your process.env!](https://thepracticaldev.s3.amazonaws.com/i/o60b5slh7kjjbp852694.png)

Check bottom for the solution. For now, let’s wander back a bit. I first thought about this problem when I found that `process.env.NODE_ENV` is typed and has code completion, while the other does not:

![NODE_ENV has code completion.](https://thepracticaldev.s3.amazonaws.com/i/33j0d4duki9z6n66axa7.png)

This piece of information had been in my mind since the first time I saw it around 2017. However, I never really looked into it too deeply as back then I had no need to leverage client-side environment variable.

At [Plasmo](www.plasmo.com), we decided to leverage client-side environment to swap between staging and production endpoints. Initially with 2 variables it was manageable. But when that number grew to 13, it became a bit annoying to lookup the .env file, as the variable names are increasingly getting longer. This annoyance can be tolerated for a while, as we were focusing on our product. However, in the back of my mind, there was a strong drive to squash this “bug.”

> Technically this is not a bug, that is why there were "”.

A big win of using TypeScript is that refactoring is a breeze, and that is the key to move fast — starting with one file, grow it to 300 loc, then split it into several files, rinse repeat. This applies to our type definition as well, as using a single `.d` (definition) file to describe both our api typing as well as our theme typing becomes convoluted. So we decided to finally split our typing into these neat files:

![typings](https://thepracticaldev.s3.amazonaws.com/i/78a4prz5x09tapw7qemn.png)

Finally, I can bid our good ol’ `react-app-env.d.ts` farewell. But much to my surprise, when resuming CRA (create-react-app) server afterward, that file was resurrected. After going through CRA's internal packages for a bit, I found that react-scripts (the main program powering CRA) was programmed to generate this file.

This is when my brain started to notice the name of this file: `react-app-env`. Every magic string has meaning, said the basic rule of edb (on Windows you can use x64dbg). To generate a file with such specific name means there was some significant use of it, probably within the organization of `${process.env.REACT_APP_AUTHOR}`.

Digging deeper with [duckduckgo.com](duckduckgo.com) with the search term “react-app-env.d.ts declare global,” the [third result](https://github.com/facebook/create-react-app/issues/5576) (note: not 1st or 2nd, but 3rd) gave some great insight, in particular, [in this comment](https://github.com/facebook/create-react-app/issues/5576#issuecomment-433613637).

![In case the github link got spike traffic
](https://thepracticaldev.s3.amazonaws.com/i/09la585qu012i0okbmgm.png)

The github issue's author was trying to tackle the “bug” at hand, and the code snippet was extremely insightful:

```
declare namespace NodeJS {
  interface ProcessEnv {
    NODE_ENV: 'development' | 'production' | 'test'
    PUBLIC_URL: string
  }
}
```

In brief, the typescripts support of CRA consume an extended definition under the NodeJS namespace. To extend it for our environment, simply put the snippet above in your `react-app-env.d.ts`

# BONUS

You now know how to extends your environment typing for some good old lazy `process.env` auto-completion. But now you need to deal with global API placed under Window (like Stripe.js). Below will save you a trip to the duck (This is a simplified version of our `react-app-env.d.ts` file:

```
/// <reference types="react-scripts" />
declare namespace NodeJS {
interface ProcessEnv {
    NODE_ENV: 'development' | 'production' | 'test'
    PUBLIC_URL: string
    REACT_APP_HASH: string
    REACT_APP_API_URI: string
    REACT_APP_WS_URI: string
    }
}
interface Window {
    Stripe: any
}

```