Open any modern repository and the first files you meet are JSON: package.json, tsconfig.json, .prettierrc, settings.json, composer.json, appsettings.json. In this lesson you will learn how to read and edit the most important ones, why some of them allow comments even though JSON does not, how the $schema key gives you autocomplete, and when a different format such as YAML or TOML is the better tool.
JSON won the configuration space for practical reasons: every language parses it, its strict grammar leaves no ambiguity, tools can rewrite it without losing structure, and editors validate it as you type. Its two weaknesses, no comments and no trailing commas, are what the variants later in this lesson address.
package.json describes a Node.js project. The sample at the top shows the fields you will touch most:
| Field | Meaning |
|-------|---------|
| name, version | Package identity; version follows semantic versioning (major.minor.patch) |
| private | true prevents accidental publishing |
| type | "module" makes .js files ES modules; omit or "commonjs" for require |
| main, exports | Entry point(s) other packages import |
| scripts | Commands run with npm run <name>; npm test and npm start are shortcuts |
| dependencies, devDependencies | Runtime vs development-only packages with version ranges |
| engines | Node.js versions the project supports |
Version ranges use semver operators: ^5.1.0 accepts any 5.x.y at or above 5.1.0, ~5.1.0 accepts only 5.1.x, and a bare 5.1.0 pins exactly. Hand-editing is fine, but npm also edits the file for you and keeps it valid:
npm pkg set scripts.build="tsc -p ." # add or change a nested key
npm pkg get version # read a value
npm pkg delete scripts.lint # remove a key
npm install express@^5 # updates dependencies for youBecause package.json is parsed with a strict parser, a single comment or trailing comma breaks every npm command with JSON.parse errors. If you need a note, the community convention is a "//" key with a string value; npm ignores keys it does not know.
The TypeScript compiler reads tsconfig.json with a lenient parser that accepts comments and trailing commas. This dialect is called JSONC (JSON with Comments) and is also used by VS Code's settings.json, launch.json, .devcontainer/devcontainer.json and Deno's config:
{
// Shared settings live in a base file; this one only overrides
"extends": "./tsconfig.base.json",
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"strict": true,
"outDir": "dist", // trailing comma is tolerated by tsc
},
"include": ["src"],
}The catch is that JSONC is not JSON: JSON.parse rejects it, and so do most standard libraries. When your own code must read such a file, use a dedicated parser such as the jsonc-parser package or strip comments first.
Most config formats publish a JSON Schema describing their allowed keys. Point a file at its schema with a top-level $schema property and your editor validates keys and values and offers completions:
{
"$schema": "https://json.schemastore.org/prettierrc",
"semi": false,
"singleQuote": true,
"printWidth": 100
}SchemaStore hosts schemas for hundreds of well-known files, and VS Code associates common names such as package.json and tsconfig.json automatically, so a misspelled "dependencies" is underlined immediately. The next lesson shows how to write a schema for your own application's config so your users get the same experience.
| Format | Comments | Trailing commas | Multiline strings | Typical use |
|--------|----------|-----------------|-------------------|-------------|
| JSON | no | no | no | package.json, APIs, data exchange |
| JSONC | yes | yes | no | tsconfig.json, VS Code settings |
| JSON5 | yes | yes | yes | Some build tools; unquoted keys, single quotes |
| YAML | yes | n/a | yes | Docker Compose, GitHub Actions, Kubernetes |
| TOML | yes | n/a | yes | pyproject.toml, Cargo.toml, .NET tooling |
Choose plain JSON when machines will read or write the file and when interoperability matters. Choose YAML or TOML for files humans author by hand that benefit from comments and less punctuation, keeping in mind YAML's own traps such as indentation sensitivity. Whatever you choose, keep secrets out: API keys belong in environment variables or a secrets manager, never in a committed file.
What happens if you add a `// comment` to `package.json`?
package.json is strict JSON; use npm pkg set/get for safe edits and a "//" key for notes.tsconfig.json, VS Code settings and similar files are JSONC: comments and trailing commas are tolerated by their tools but not by JSON.parse.$schema property gives any JSON config file editor validation and autocomplete.Next lesson: JSON Schema and Validation — describe the exact shape a JSON document must have and validate data automatically.