Skip to content Skip to footer

Taming Environment Variables in JavaScript: A Developer’s Guide

Hey, fellow devs! Today, we’re diving deep into the world of environment variables in JavaScript. You know the drill—those sneaky little key-value pairs that hold the secrets to our app’s configuration, keeping our sensitive data out of the prying eyes of the public repo.

Environment variables are like the backstage passes to your app’s performance. Get them right, and you’re the rockstar of security and scalability. Mess them up, and well, let’s not go there. So, let’s get our hands dirty and explore how to manage them across different JavaScript frameworks.

Vanilla JavaScript and Node.js

Starting with the basics, in Node.js, environment variables are accessed via the global process.env object—a simple yet powerful feature. Here’s a quick example for setting and getting an environment variable:

// Set an environment variable in the terminal before running the app
// In Unix-based systems:
// export SECRET_CODE=abc123
// In Windows Command Prompt:
// set SECRET_CODE=abc123

// Accessing the environment variable in your Node.js app
const secretCode = process.env.SECRET_CODE;
console.log(`The secret code is: ${secretCode}`);

But what if you want to manage your environment variables more gracefully? Enter dotenv, a module that loads environment variables from a .env file into process.env. Install it with npm install dotenv and create a .env file at the root of your project:

# .env file
DB_HOST=localhost
DB_USER=root
DB_PASS=s1mpl3

Then, in your main file:

require('dotenv').config();

console.log(process.env.DB_HOST); // 'localhost'
console.log(process.env.DB_USER); // 'root'
console.log(process.env.DB_PASS); // 's1mpl3'

React and Create React App

For React devs, particularly those using Create React App (CRA), managing environment variables is a breeze. CRA comes with built-in support for environment variables, but with a catch—they must begin with REACT_APP_ to be embedded into the build.

Here’s the lowdown:

// In your .env file
REACT_APP_API_URL=https://myapi.com
REACT_APP_GA_TRACKING_ID=UA-123456-2

Then, in your React components:

console.log(process.env.REACT_APP_API_URL); // 'https://myapi.com'
console.log(process.env.REACT_APP_GA_TRACKING_ID); // 'UA-123456-2'

Remember, CRA will only load the .env file during the build process, so changes to environment variables require a rebuild.

Vue.js and the Vue CLI

Vue.js developers, you’re not left out. The Vue CLI provides a similar setup to CRA. Prefix your environment variables with VUE_APP_ and you’re golden.

Your .env file might look like this:

# .env file
VUE_APP_BASE_URL=https://myvueapp.com
VUE_APP_SECRET_KEY=letmein

And in your Vue components:

console.log(process.env.VUE_APP_BASE_URL); // 'https://myvueapp.com'
console.log(process.env.VUE_APP_SECRET_KEY); // 'letmein'

Vue CLI also supports .env files for different modes, like .env.development or .env.production, which is super handy for maintaining different settings across environments.

Angular and Environment Files

Angular takes a slightly different approach. Instead of using .env files, it uses environment-specific TypeScript files. You’ll find them in the environments folder:

// environments/environment.prod.ts
export const environment = {
  production: true,
  apiUrl: 'https://api.myangularapp.com',
  apiKey: 'supersecret'
};

And in your Angular components:

import { environment } from '../environments/environment';

console.log(environment.apiUrl); // 'https://api.myangularapp.com'
console.log(environment.apiKey); // 'supersecret'

Angular’s CLI environment options are straightforward and integrate seamlessly with the build process.

Alright, that’s a wrap for the first half of our environment variables extravaganza. We’ve covered the basics and the handling in Node.js, React, Vue.js, and Angular. Stay tuned for the second half, where we’ll explore more advanced scenarios and best practices for keeping your environment variables secure and scalable. See you in the next commit!

Welcome back, code wranglers! We’ve already laid the groundwork for environment variable management in various JavaScript frameworks. Now, let’s kick it up a notch and delve into some advanced tactics to keep your configs both secure and developer-friendly.

Next.js and the Power of Server-Side Secrets

Next.js, the React framework for production, provides a smooth developer experience when it comes to environment variables. It supports loading environment variables at build time for the client-side, but it also has a trick up its sleeve for server-side secrets.

Here’s how you can set up public runtime config in Next.js:

// next.config.js
module.exports = {
  publicRuntimeConfig: {
    API_ENDPOINT: process.env.API_ENDPOINT // Pass through env variables
  }
};

And for server-side secrets that should not be exposed to the browser:

// next.config.js
module.exports = {
  serverRuntimeConfig: {
    MY_SECRET: process.env.MY_SECRET // Only available on the server side
  }
};

// pages/some-server-side-page.js
import getConfig from 'next/config';
const { serverRuntimeConfig } = getConfig();

console.log(serverRuntimeConfig.MY_SECRET); // Available server-side only

Remember, Next.js allows you to prefix your environment variables with NEXT_PUBLIC_ to expose them to the browser, similar to CRA’s REACT_APP_.

Gatsby and Environment Variables at Build Time

Gatsby, the static site generator for React, also provides a robust system for handling environment variables. You can define environment variables in a .env.development or .env.production file, and Gatsby will make them available during the build process.

To access these variables in your Gatsby components, you can use GraphQL:

export const query = graphql`
  {
    site {
      siteMetadata {
        title
      }
    }
  }
`;

// Use the data prop injected by the GraphQL query
const MyComponent = ({ data }) => {
  console.log(data.site.siteMetadata.title);
  return <h1>{data.site.siteMetadata.title}</h1>;
};

For public variables, you can use the GATSBY_ prefix to expose them to the client side.

Securing Your Secrets with Environment Variable Best Practices

Now that we’ve covered the technical how-tos, let’s talk security. Your environment variables often contain sensitive information that you wouldn’t want to expose. Here are some best practices to keep your secrets safe:

  • Never commit sensitive data: Always add .env files to your .gitignore. For Angular, ignore the non-default environment files.
  • Use environment variable managers: Services like Doppler or HashiCorp Vault can help manage and inject secrets into your app securely.
  • Limit access: Only give access to environment variables to the parts of your application that truly need them.
  • Use secret management tools: If you’re deploying with platforms like AWS, GCP, or Azure, leverage their secret management tools to keep your credentials secure.

Continuous Integration and Environment Variables

When it comes to CI/CD pipelines, you’ll need to ensure that your environment variables are accessible during the build and deploy stages. Services like GitHub Actions, Travis CI, and CircleCI allow you to set environment variables securely in their respective dashboards.

Here’s an example of how you might configure environment variables in a GitHub Actions workflow:

# .github/workflows/deploy.yml
name: Deploy

on: [push]

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
    - name: Checkout Repo
      uses: actions/checkout@v2
    - name: Set up Node.js
      uses: actions/setup-node@v1
      with:
        node-version: '14'
    - name: Install Dependencies
      run: npm install
    - name: Build
      run: npm run build
      env:
        REACT_APP_API_KEY: ${{ secrets.REACT_APP_API_KEY }} # Use secrets from GitHub
    - name: Deploy
      run: some-deploy-script.sh

In this example, REACT_APP_API_KEY is stored securely in GitHub’s secrets and only used during the build process.

Wrapping Up

There you have it—a comprehensive guide to mastering environment variables in the JavaScript ecosystem. Whether you’re working with Node.js, React, Vue.js, Angular, Next.js, or Gatsby, you now have the tools to manage your app’s configuration like a pro.

Remember, the key to effective environment variable management is to keep your secrets secure, your public configs accessible, and your development process smooth. Now go forth and configure responsibly! 🚀