Dynamic JavaScript and React Configuration

11 May 2020

Most of the frontends we build at Lithic are written in React. Normally we deploy them as static apps in Netlify. This will write environment variables from process.env directly into the compiled JavaScript.

Sometimes, though, we need to dynamically configure the applications based on runtime, not build time, environment variables. The basic create-react-app workflow doesn't work in this situation.

There are many approaches to runtime configuration of static JavaScript applications. Most of them involve writing out a config.js file at server boot time, and having the client load this before or alongside the main JS bundle. In some solutions, the JS is dynamically templated.

All of these approaches have downsides:

  • Loading config.js before your main bundle introduces latency before you can load your app.
  • Loading config.js alongside your main bundle means your app cannot synchronously access config, which introduces complexity.
  • Templating your main bundle on each request is nontrivially complex (we love nginx too but the fewer script callouts the better).

There is a solution, though: template config directly into index.html at server/container boot time.

Our Solution

We built runtime-js-env to handle dynamic JS config with no downsides. It's a simple Go program that rewrites index.html to include a window._jsenv object with your config pulled from REACT_APP_, NODE_, and HEROKU_ environment variables.

You call it at container/server boot time, and the only change you need to make in your JS is change calls to process.env into calls to window._jsenv || process.env. See the GitHub repo for some examples of how we handle this.

Your index.html file will be modified to include a <script> tag inside your <head>. It's safe to call multiple times, and uses Go's HTML5 parser so should be valid for whatever you throw at it.

Usage

runtime-js-env is a Go program, so you'll need Go installed.

$ go get github.com/lithictech/runtime-js-env
$ runtime-js-env --help
NAME:
   runtime-js-env - A new cli application

USAGE:
   runtime-js-env [global options] command [command options] [arguments...]

COMMANDS:
   help, h  Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --index value, -i value            Path to the index.html file. Default to index.html in pwd. (default: "index.html")
   --window-var-name value, -w value  Attribute name for the config object. (default: "_jsenv")
   --env-prefixes value, -p value     Environment variable prefixes to copy into the config object. (default: "REACT_APP_", "NODE_", "HEROKU_")
   --indent value, -t value           Indentation for each line in the config script tag. (default: "  ")
   --help, -h                         show help (default: false)
$ runtime-js-env -i public/index.html

Feedback

If you have any suggestions or feedback, please open an issue or get in touch directly.

Lithic Tech was founded in Portland, Oregon by experienced software engineers with a track record of high-quality software, happy customers, and successful businesses. We believe this success is a result of our unique processes, patterns, and convictions.

We are now offering that expertise to the wider community to build better software and software teams. You can learn more about us, and we’d love if you got in touch.

Email us at hello@lithic.tech or use this form: