How to Configure Environment Variables Using the @extension/env Package

The @extension/env package centralizes environment management by loading .env files prefixed with CEB_, supporting CLI overrides via CLI_CEB_ flags, and exporting typed constants like IS_DEV for type-safe access throughout your Chrome extension codebase.

The jonghakseo/chrome-extension-boilerplate-react-vite repository streamlines Chrome extension development through a monorepo architecture where environment configuration is isolated in a dedicated package. When you configure environment variables using the @extension/env package, you gain validation, TypeScript autocomplete, and runtime safety across content scripts, background workers, and popup components. The package uses @dotenvx/dotenvx internally and enforces strict naming conventions to prevent collisions with system variables.

Defining Variables in the .env File

All extension-specific environment variables must use the CEB_ prefix to be recognized by the validation logic. This naming convention ensures that only intended values are injected into the build while keeping system environment variables separate.

The CEB_ Prefix Requirement

Create or edit the .env file in the repository root and add your variables:

CEB_API_KEY=your_secret_key_here
CEB_API_ENDPOINT=https://api.example.com
CEB_DEBUG_MODE=true

Without the CEB_ prefix, variables are ignored by the loading mechanism in packages/env/lib/config.ts.

Configuration Loading Mechanism

The package loads these values at build time through packages/env/lib/config.ts, which uses @dotenvx/dotenvx to parse the file:

// packages/env/lib/config.ts
import { config } from '@dotenvx/dotenvx';
export const baseEnv = config({
  path: `${import.meta.dirname}/../../../../.env`,
}).parsed ?? {};

This baseEnv object becomes the foundation for all derived constants and type definitions exported by the package.

Overriding Values from the Command Line

For temporary overrides during development or CI/CD pipelines, the repository supports CLI-based environment injection without modifying the .env file permanently.

Using CLI_CEB_ Prefixes

Pass variables with the CLI_CEB_ prefix to override values for a single command execution. These take precedence over the .env file but do not persist after the script completes.

pnpm set-global-env CLI_CEB_API_KEY=tmp_staging_key
pnpm dev

Valid boolean flags include CLI_CEB_DEV and CLI_CEB_FIREFOX, which control build-time behavior.

The set-global-env Helper Script

The bash-scripts/set_global_env.sh script validates the prefix and rewrites the .env file temporarily to place CLI values under a dedicated read-only section. This script checks for the CLI_CEB_ pattern and validates boolean flags before injection, ensuring that only approved configuration keys reach the build process.

Accessing Environment Variables in Extension Code

Once defined, you can access these values through two primary mechanisms: direct process.env access for arbitrary keys or typed imports for common boolean flags.

Direct process.env Access

Any variable starting with CEB_ is available on process.env with full TypeScript autocomplete support:

// src/feature.ts
console.log(process.env.CEB_API_KEY);
// Alternative syntax for dynamic keys
console.log(process.env['CEB_API_ENDPOINT']);

As documented in packages/env/README.md, both bracket and dot notation work correctly within the Vite build system.

Typed Boolean Constants

For frequently checked flags, import typed constants from packages/env/lib/const.ts:

import { IS_DEV, IS_FIREFOX, IS_PROD, IS_CI } from '@extension/env';

if (IS_DEV) {
  console.log('Development mode active');
}

if (IS_FIREFOX) {
  // Firefox-specific polyfills
}

These constants are derived from CLI flags and environment values:

// packages/env/lib/const.ts
export const IS_DEV = process.env['CLI_CEB_DEV'] === 'true';
export const IS_PROD = !IS_DEV;
export const IS_FIREFOX = process.env['CLI_CEB_FIREFOX'] === 'true';
export const IS_CI = process.env['CEB_CI'] === 'true';

Dynamic Derived Values

You can compute complex environment values in packages/env/lib/index.ts by extending the dynamicEnvValues object. The default implementation sets CEB_NODE_ENV based on the CEB_DEV flag:

// packages/env/lib/index.ts
export const dynamicEnvValues = {
  CEB_NODE_ENV: baseEnv.CEB_DEV === 'true' ? 'development' : 'production',
} as const;

Add custom derived keys here to expose computed URLs, version strings, or feature flags. These values become part of the exported EnvType defined in packages/env/lib/types.ts.

Build Script Integration

The root package.json wires the environment helper into standard npm scripts to ensure flags are populated before Vite executes:

  • pnpm dev runs pnpm set-global-env CLI_CEB_DEV=true && pnpm base-dev
  • pnpm build runs pnpm set-global-env && pnpm base-build
  • pnpm build:firefox runs pnpm set-global-env CLI_CEB_FIREFOX=true && pnpm base-build

These commands guarantee that IS_DEV and IS_FIREFOX are correctly set during the build lifecycle, enabling conditional compilation and runtime branching.

Summary

  • Prefix requirement: All custom variables must start with CEB_ in the .env file to be loaded by packages/env/lib/config.ts.
  • CLI overrides: Use CLI_CEB_ prefixes with pnpm set-global-env to temporarily override values without editing files.
  • Typed access: Import IS_DEV, IS_FIREFOX, and other booleans from @extension/env for type-safe runtime checks.
  • Dynamic values: Extend dynamicEnvValues in packages/env/lib/index.ts to expose computed environment properties.
  • Build integration: The set-global-env script runs automatically via pnpm dev and pnpm build to ensure consistent environment state.

Frequently Asked Questions

How do I add a new environment variable to the Chrome extension?

Add the variable to your root .env file with the CEB_ prefix, such as CEB_NEW_FEATURE=true. The @dotenvx/dotenvx loader in packages/env/lib/config.ts will automatically pick it up, and you can access it via process.env.CEB_NEW_FEATURE in any extension script.

What is the difference between CEB_ and CLI_CEB_ prefixes?

Variables with the CEB_ prefix are read from the .env file and represent persistent configuration. The CLI_CEB_ prefix is used for temporary overrides passed through the command line via pnpm set-global-env, which rewrites the environment only for the current command execution without persisting changes to the repository.

Can I use process.env directly instead of importing from @extension/env?

Yes, direct process.env access works for any CEB_ prefixed variable, and the package provides TypeScript definitions for autocomplete. However, importing typed constants like IS_DEV from @extension/env is recommended for boolean flags because they provide compile-time type safety and cleaner syntax than checking process.env['CLI_CEB_DEV'] === 'true' manually.

Where are the TypeScript types for environment variables defined?

The type definitions live in packages/env/lib/types.ts, which exports EnvType combining baseEnv and dynamicEnvValues. This ensures that TypeScript knows which keys are available on process.env when you import the package, enabling IntelliSense autocomplete for custom CEB_ variables you add to the system.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →