⚙️ Day 4 — Load Configuration & Environment

7 min read·Jan 1, 2026

Welcome to Day 4.

In yesterday's lesson, you started persisting data by storing notes on disk instead of keeping them in memory.

In today's lesson, you'll make LBNotes configurable using environment variables.

You'll learn how .env files are used to control behavior without touching code — for example, changing where notes are stored — and why this is the standard way to configure backend projects.

By the end of this lesson, you'll be able to change LBNotes' behavior by editing .env, without modifying your JavaScript files.

Create an .env file

An .env file is a plain text file that allows developers to keep configuration outside of the code and load it into the process environment when running a CLI tool.

Within the project's directory, let's create a new file named .env.

~/projects/
└─ lb_notes/
   ├─ .env
   ├─ bin/
   ├─ package.json
   └─ src/
      ├─ cli/
      └─ storage/

Within this file, let's write the following configuration variable into it that holds the path to the JSON file into which the notes are stored.

.env
LB_NOTES_FILE_PATH=data/notes.json

💡 In .env files, variables are declared as key-value pairs, where each pair is represented by a variable name usually written in upper snake case, followed by the equal sign (=), followed by a variable value.

Create a configuration loader

Within the src directory, let's create a new directory named config, and within it, a new file named load_env.js.

~/projects/
└─ lb_notes/
   ├─ .env
   ├─ bin/
   ├─ package.json
   └─ src/
      ├─ cli/
      ├─ config/
      │  └─ load_env.js
      └─ storage/

Within this file, let's export a loadEnv() function whose role is to load the variables present in the .env file into the process environment.

src/config/load_env.js
import { loadEnvFile } from 'node:process';

export default function loadEnv() {
  loadEnvFile();
}

💡 By default, the loadEnvFile() function will load the content of the .env file.

Load and use the configuration

Let's update the CLI router to execute the loadEnv() function and use the value of the LB_NOTES_FILE_PATH environment variable loaded from the .env file as path to the JSON file used to store the notes, or the data/notes.json path as a fallback value.

src/cli/index.js
import path from 'node:path';
import parseArgs from './parse_args.js';
import loadEnv from '../config/load_env.js';
import help from './commands/help.js';
import add from './commands/add.js';
import list from './commands/list.js';

export default function run(args) {
  try {
    loadEnv();
    const { command, value } = parseArgs(args);
    const NOTES_FILE_PATH = path.resolve(process.env.LB_NOTES_FILE_PATH || 'data/notes.json');

    // ...
  } catch(error) {
    console.error(`lb_notes: error: ${error.message}`);
    return 1;
  }
  return 0;
}

💡 In Node.js, environment variables are stored in the global process.env object.

Test the CLI

Within the .env file, let's change the path to the JSON file to "tmp/data.json".

.env
LB_NOTES_FILE_PATH=tmp/data.json

Let's create a new note using the add subcommand.

~/projects/lb_notes$ lb_notes add "Free scheduled appointments on Sunday"
Note saved!

Let's output the stored notes using the list subcommand.

~/projects/lb_notes$ lb_notes list
[ 'Free scheduled appointments on Sunday' ]

Let's check that the content is written to and loaded from tmp/data.json instead of data/notes.json.

~/projects/lb_notes$ cat tmp/data.json
{
  "notes": [
    "Free scheduled appointments on Sunday"
  ]
}