Learn/Practical Guides

JSON Config Files — package.json, tsconfig & Beyond

Every modern project has JSON config files. This guide explains the most important ones — what each field does, common mistakes to avoid, and the best practices that save hours of debugging.

Beginner~14 min read

Common JSON Config Files

FileToolPurpose
package.jsonnpm / yarn / pnpmProject metadata, scripts, dependencies
tsconfig.jsonTypeScriptCompiler options, path aliases, strictness
.eslintrc.jsonESLintLinting rules, plugins, environments
settings.jsonVS CodeEditor preferences, formatting, extensions
.prettierrcPrettierCode formatting rules
nest-cli.jsonNestJSCLI configuration, project structure
vercel.jsonVercelDeployment settings, rewrites, headers
firebase.jsonFirebaseHosting rules, functions config

package.json — The Heart of Every Node Project

Annotated package.jsonjson
1{
2 "name": "my-app",
3 "version": "1.0.0",
4 "description": "A production web application",
5 "private": true,
6 "type": "module",
7 "main": "dist/index.js",
8 "scripts": {
9 "dev": "next dev --port 3000",
10 "build": "next build",
11 "start": "next start",
12 "lint": "eslint . --ext .ts,.tsx",
13 "test": "vitest run",
14 "typecheck": "tsc --noEmit"
15 },
16 "dependencies": {
17 "next": "^15.5.0",
18 "react": "^19.0.0",
19 "react-dom": "^19.0.0"
20 },
21 "devDependencies": {
22 "@types/node": "^22.0.0",
23 "@types/react": "^19.0.0",
24 "typescript": "^5.7.0",
25 "eslint": "^9.0.0"
26 },
27 "engines": {
28 "node": ">=20.0.0"
29 }
30}

Key Fields Explained

"private": true

Prevents accidental publish to npm. Always set for application projects (not libraries).

"type": "module"

Enables ES modules (import/export) instead of CommonJS (require). Modern Node.js projects should use this.

"engines"

Declares the minimum Node.js version. npm will warn (or error with engine-strict) if the version doesn't match.

Version Ranges Matter

^15.5.0 allows 15.5.0 through 15.x.x. ~15.5.0 allows only 15.5.x. For production apps, use ^ for minor updates or pin exact versions with a lockfile.

tsconfig.json — TypeScript Compiler Configuration

Production-ready tsconfig.jsonjson
1{
2 "compilerOptions": {
3 "target": "ES2022",
4 "module": "ESNext",
5 "moduleResolution": "bundler",
6 "lib": ["ES2022", "DOM", "DOM.Iterable"],
7
8 "strict": true,
9 "noUncheckedIndexedAccess": true,
10 "noUnusedLocals": true,
11 "noUnusedParameters": true,
12 "forceConsistentCasingInFileNames": true,
13
14 "jsx": "react-jsx",
15 "esModuleInterop": true,
16 "skipLibCheck": true,
17 "resolveJsonModule": true,
18 "isolatedModules": true,
19
20 "baseUrl": ".",
21 "paths": {
22 "@/*": ["./src/*"]
23 },
24
25 "outDir": "dist",
26 "declaration": true,
27 "sourceMap": true
28 },
29 "include": ["src/**/*.ts", "src/**/*.tsx"],
30 "exclude": ["node_modules", "dist"]
31}

Essential Strict Options

OptionWhat It DoesRecommended
strictEnables all strict checks at once✓ Always
noUncheckedIndexedAccessarray[i] returns T | undefined✓ Catches bugs
noUnusedLocalsError on unused variables✓ Clean code
forceConsistentCasingInFileNamesPrevents case-mismatch imports✓ Cross-platform
isolatedModulesRequired for bundlers (esbuild, swc)✓ Modern setups

Path Aliases

The paths field lets you write import { Button } from '@/components/Button' instead of relative paths like ../../components/Button.

VS Code settings.json

Workspace settings (.vscode/settings.json)json
1{
2 "editor.formatOnSave": true,
3 "editor.defaultFormatter": "esbenp.prettier-vscode",
4 "editor.codeActionsOnSave": {
5 "source.fixAll.eslint": "explicit"
6 },
7 "editor.tabSize": 2,
8 "editor.rulers": [100],
9 "files.trimTrailingWhitespace": true,
10 "files.insertFinalNewline": true,
11 "typescript.tsdk": "node_modules/typescript/lib",
12 "json.schemas": [
13 {
14 "fileMatch": ["package.json"],
15 "url": "https://json.schemastore.org/package"
16 }
17 ]
18}

Workspace vs User Settings

Workspace settings live in .vscode/settings.json and are committed to the repo — shared with the team. User settings are global to your machine and should not be committed.

.prettierrc — Formatting Rules

Common Prettier configjson
1{
2 "semi": false,
3 "singleQuote": true,
4 "trailingComma": "all",
5 "tabWidth": 2,
6 "printWidth": 100,
7 "arrowParens": "avoid",
8 "endOfLine": "lf",
9 "bracketSpacing": true
10}

vercel.json — Deployment Configuration

Vercel deployment configjson
1{
2 "framework": "nextjs",
3 "regions": ["iad1"],
4 "headers": [
5 {
6 "source": "/api/(.*)",
7 "headers": [
8 { "key": "Cache-Control", "value": "no-store" },
9 { "key": "X-Content-Type-Options", "value": "nosniff" }
10 ]
11 }
12 ],
13 "rewrites": [
14 { "source": "/blog/:path*", "destination": "/learn/:path*" }
15 ],
16 "redirects": [
17 { "source": "/old-page", "destination": "/new-page", "permanent": true }
18 ]
19}

Config File Best Practices

Always validate config JSON syntax before committing
Use JSON Schema for IntelliSense (schemastore.org)
Share workspace settings via .vscode/settings.json
Pin dependency versions with a lockfile
Keep tsconfig strict from day one
Document custom scripts in a README
Use path aliases to avoid deep relative imports
Set editor.formatOnSave for consistent formatting

Try It Yourself

Here is a minimal package.json. Try adding scripts, dependencies, or an engines field.

Try It Yourself

Edit this package.json and validate

Frequently Asked Questions

Why do config files use JSON?
JSON is language-agnostic, human-readable, and has universal parser support in every language. It enforces a strict structure that prevents ambiguity, making it ideal for tool configuration.
Can I add comments to package.json?
No. package.json must be valid JSON, which does not support comments. You can use a "//" key as a convention: "//" : "This is a note", but linters may warn about it.
What is the difference between tsconfig.json and jsconfig.json?
tsconfig.json configures TypeScript projects. jsconfig.json is the JavaScript equivalent — it enables IntelliSense and path aliases for pure JavaScript projects. Both share the same schema.
Should I use .json or .js for ESLint config?
ESLint supports both. JSON is simpler but cannot use dynamic logic. JavaScript (.eslintrc.js or eslint.config.js in flat config) allows conditional rules, imports, and shared configs.
How do I validate a JSON config file?
Use a JSON Schema validator. Most config files have official JSON Schemas published at schemastore.org. VS Code uses these automatically for IntelliSense in config files.