Managing Configuration Files with JSON
JSON config files are everywhere. Your package.json, tsconfig.json, prettier config, VS Code settings, and probably half the tools in your project use them. Here's how to work with them effectively.
Common JSON Config Files
You'll run into these constantly in JavaScript projects:
package.json- Node.js project metadata and dependenciestsconfig.json- TypeScript compiler optionsjsconfig.json- JavaScript project settings for editors.prettierrc- Prettier code formatter config.eslintrc.json- ESLint rules and settingsbabel.config.json- Babel transpiler config.vscode/settings.json- VS Code workspace settingsvercel.json,netlify.json- Deployment settings
Understanding package.json
This is the most important config file in any Node.js project. Here's what the fields mean:
{
"name": "my-app",
"version": "1.0.0",
"description": "A cool application",
"main": "index.js",
"scripts": {
"start": "node index.js",
"dev": "nodemon index.js",
"test": "jest",
"build": "tsc"
},
"dependencies": {
"express": "^4.18.2"
},
"devDependencies": {
"jest": "^29.5.0",
"nodemon": "^3.0.0"
},
"engines": {
"node": ">=18.0.0"
}
}
Key fields explained
- name - Package name, used for npm publishing
- version - Semantic version (major.minor.patch)
- main - Entry point when your package is imported
- scripts - Commands you run with
npm run [name] - dependencies - Packages needed in production
- devDependencies - Packages only needed during development
- engines - Required Node.js version
Version ranges in dependencies
"express": "4.18.2"- Exact version only"express": "^4.18.2"- Compatible with 4.x.x"express": "~4.18.2"- Compatible with 4.18.x"express": "*"- Any version (risky)
Environment Specific Configs
A common pattern is having different configs for development, staging, and production.
The layered approach
config/
config.default.json # Base settings
config.development.json
config.staging.json
config.production.json
Merging configs in code
const fs = require('fs');
function loadConfig() {
const env = process.env.NODE_ENV || 'development';
const defaultConfig = JSON.parse(
fs.readFileSync('./config/config.default.json')
);
const envConfig = JSON.parse(
fs.readFileSync(`./config/config.${env}.json`)
);
// Environment config overrides defaults
return { ...defaultConfig, ...envConfig };
}
const config = loadConfig();
Keep secrets out of JSON
Never put passwords, API keys, or other secrets in JSON config files. Use environment variables instead:
{
"database": {
"host": "localhost",
"port": 5432,
"name": "myapp"
}
}
// Load password from environment
const dbPassword = process.env.DB_PASSWORD;
const dbConfig = {
...config.database,
password: dbPassword
};
Best Practices
1. Keep configs small
If your config file is hundreds of lines, something's wrong. Split it up or use a different approach.
2. Document non-obvious settings
JSON doesn't support comments, but you can use a README or add
"_comment" fields:
{
"_comment": "Timeout is in milliseconds",
"timeout": 30000
}
Some tools also support JSONC (JSON with Comments). Check if yours does.
3. Use schema validation
Many config formats have JSON schemas. VS Code will give you autocomplete and validation if you specify the schema:
{
"$schema": "https://json.schemastore.org/tsconfig",
"compilerOptions": {
"strict": true
}
}
4. Version control your configs
Check in your config files (except secrets). They're part of your project. Use
.gitignore for local overrides.
5. Provide sensible defaults
Your app should work with minimal config. Require only what's absolutely necessary.
When Not to Use JSON
JSON is great, but sometimes other formats are better:
Use YAML when:
- Humans edit the file frequently (more readable)
- You need comments in the config
- Working with DevOps tools (Kubernetes, Docker Compose)
Use TOML when:
- You want comments but find YAML too complex
- Working with Rust projects (Cargo.toml)
Use environment variables when:
- Storing secrets
- Values change between deployments
- Running in containers
Use JavaScript/TypeScript config when:
- You need computed values or functions
- Type safety is important
- Complex conditional logic
// config.js - Can use logic and environment vars
module.exports = {
port: process.env.PORT || 3000,
debug: process.env.NODE_ENV !== 'production',
features: {
newDashboard: process.env.ENABLE_NEW_DASHBOARD === 'true'
}
};
Useful Tooling
VS Code extensions
- JSON Schema Store - Auto-detects schemas for common configs
- Prettier - Formats JSON files on save
Command line
jq- Query and transform JSON from the terminalnpx json5- Convert JSON5 (with comments) to JSON
Online tools
Need to clean up messy config files? Our JSON tool can remove empty values and format your configs.