Environment Variables and Application Configuration
Applications should not hardcode database connection strings throughout their source code. Environment-based configuration makes it easier to separate development, testing, staging, and production settings.
Example project structure
my-node-app/
src/
db.js
server.js
.env
.gitignore
package.json
The exact structure depends on the application. The important principle is that sensitive configuration is managed outside committed application source code.
Example environment file
MONGODB_URI=mongodb://127.0.0.1:27017/learning
NODE_ENV=development
This example assumes a local development server without authentication. For an authenticated deployment, use an appropriate connection string and store the credentials securely.
Prevent secrets from entering source control
Add the environment file to .gitignore:
.env
.env.local
.env.*.local
If a secret was already committed, adding the file to .gitignore does not remove it from Git history or invalidate the exposed credential. Rotate the credential and follow the repository's secret-remediation process.
Loading variables in Node.js
Modern Node.js versions support loading environment files through built-in command-line options. For projects using a dotenv package, configuration can be loaded explicitly.
For example, install dotenv if your project uses that approach:
npm install dotenv
Then load the configuration before accessing the environment variable:
import dotenv from "dotenv";
dotenv.config();
const uri = process.env.MONGODB_URI;
if (!uri) {
throw new Error("MONGODB_URI is missing");
}
Alternatively, configure your runtime or hosting platform to supply environment variables directly. Avoid loading the same environment file unnecessarily in many modules.
Next.js considerations
For a Next.js application, database access should occur in server-side code. Keep the MongoDB URI in a server-only variable such as MONGODB_URI.
Do not use NEXT_PUBLIC_MONGODB_URI. Variables with the NEXT_PUBLIC_ prefix are intended for values that can be exposed to browser-side code.
In the Pages Router, database operations may be performed in API routes or other server-side code. In the App Router, they may be performed in appropriate server-side route handlers or server components, depending on the architecture.
Production configuration
Production applications should obtain secrets from an appropriate secret manager or the hosting platform's protected environment configuration. Limit access to the credentials, rotate them when necessary, and avoid printing connection strings in logs.
Environment variables help organize configuration; they do not automatically encrypt every value or prevent access by processes that have permission to read them.
A MongoDB connection URI may grant direct database access. Keep it on the server, restrict database privileges, and never return it in an API response or include it in browser bundles.
const mongodbUri = process.env.MONGODB_URI;
if (typeof mongodbUri !== "string" || mongodbUri.length === 0) {
throw new Error("Missing required environment variable: MONGODB_URI");
}
export const databaseConfig = {
uri: mongodbUri
};- Environment variables separate configuration from source code.
- A
.gitignoreentry prevents ordinary future tracking but does not erase previously committed secrets. - Node.js can read environment variables through
process.env. - Next.js database operations should use server-side code.
- Environment variables are not a replacement for access control and secret management.
Why should a MongoDB connection string containing credentials not use the `NEXT_PUBLIC_` prefix in Next.js?