for JavaScript
The complete guide to using JSON5 in JavaScript and Node.js projects.
TL;DR: Install with npm install json5, import with import JSON5 from 'json5', then use JSON5.parse() and JSON5.stringify() just like the native JSON methods.
Installation
The official JSON5 package is available on npm and is the reference implementation maintained by the JSON5 community.
npm
npm install json5Yarn
yarn add json5pnpm
pnpm add json5Bun
bun add json565M+
Weekly downloads
~6KB
Minified size
0
Dependencies
Basic Usage
ES Modules (Recommended)
import JSON5 from 'json5'; // Parse JSON5 string to JavaScript object const obj = JSON5.parse(`{ // This is a comment name: 'my-app', version: '1.0.0', features: [ 'comments', 'trailing commas', ], }`); console.log(obj.name); // 'my-app' console.log(obj.features[0]); // 'comments'CommonJS
const JSON5 = require('json5'); const config = JSON5.parse(configString); console.log(config);Stringify JavaScript to JSON5
const obj = { name: 'my-app', debug: true, ports: [3000, 3001], }; // Convert to JSON5 string const json5String = JSON5.stringify(obj, null, 2); console.log(json5String); /* { name: 'my-app', debug: true, ports: [ 3000, 3001, ], } */API Reference
The JSON5 API mirrors the native JSON API for familiarity, with some additional options.
JSON5.parse(text, reviver?)
Parses a JSON5 string and returns the corresponding JavaScript value.
Parameters
| Parameter | Type | Description |
|---|---|---|
text | string | The JSON5 string to parse |
reviver | function? | Optional transform function called for each key-value pair |
Example with Reviver
// Convert date strings to Date objects const obj = JSON5.parse(`{ created: '2024-01-15T10:30:00Z', }`, (key, value) => { if (key === 'created') { return new Date(value); } return value; }); console.log(obj.created instanceof Date); // trueJSON5.stringify(value, replacer?, space?)
Converts a JavaScript value to a JSON5 string.
Parameters
| Parameter | Type | Description |
|---|---|---|
value | any | The value to convert |
replacer | function | array? | Transform function or array of property names to include |
space | number | string? | Indentation (number of spaces or string) |
Options Object (Alternative)
JSON5.stringify also accepts an options object as the second parameter:
const str = JSON5.stringify(obj, { replacer: null, space: 2, quote: "'", // Use single quotes });Stringify Options
| Option | Type | Default | Description |
|---|---|---|---|
replacer | function | array | null | Same as JSON.stringify replacer |
space | number | string | null | Indentation level |
quote | string | "'" | Quote character for strings |
Reading JSON5 Files
Common patterns for loading JSON5 configuration files in Node.js.
Synchronous (Simple)
import JSON5 from 'json5'; import { readFileSync } from 'fs'; function loadConfig(path) { const content = readFileSync(path, 'utf8'); return JSON5.parse(content); } const config = loadConfig('./config.json5'); console.log(config);Asynchronous (Recommended for Large Files)
import JSON5 from 'json5'; import { readFile } from 'fs/promises'; async function loadConfig(path) { const content = await readFile(path, 'utf8'); return JSON5.parse(content); } // Usage const config = await loadConfig('./config.json5');With Error Handling
import JSON5 from 'json5'; import { readFileSync, existsSync } from 'fs'; function loadConfig(path, defaults = {}) { if (!existsSync(path)) { console.warn(`Config not found: ${path}, using defaults`); return defaults; } try { const content = readFileSync(path, 'utf8'); return { ...defaults, ...JSON5.parse(content) }; } catch (error) { if (error instanceof SyntaxError) { console.error(`Invalid JSON5 in ${path}:`, error.message); } throw error; } } const config = loadConfig('./config.json5', { debug: false, port: 3000, });Using require() Hook (Node.js)
Register JSON5 as a require handler to import .json5 files directly:
// At application startup require('json5/lib/register'); // Now you can require .json5 files const config = require('./config.json5');TypeScript Support
The JSON5 package includes built-in TypeScript type definitions. No additional @types package needed.
Basic TypeScript Usage
import JSON5 from 'json5'; interface AppConfig { name: string; version: string; debug: boolean; port: number; } const configString = `{ name: 'my-app', version: '1.0.0', debug: true, port: 3000, }`; // Type assertion const config = JSON5.parse(configString) as AppConfig; console.log(config.name); // TypeScript knows this is a string console.log(config.port); // TypeScript knows this is a numberType-Safe Config Loader
import JSON5 from 'json5'; import { readFileSync } from 'fs'; interface DatabaseConfig { host: string; port: number; database: string; ssl: boolean; } interface AppConfig { name: string; database: DatabaseConfig; } function loadConfig<T>(path: string): T { const content = readFileSync(path, 'utf8'); return JSON5.parse(content) as T; } const config = loadConfig<AppConfig>('./config.json5'); console.log(config.database.host); // Fully typedWith Zod Validation
import JSON5 from 'json5'; import { z } from 'zod'; import { readFileSync } from 'fs'; const ConfigSchema = z.object({ name: z.string(), port: z.number().int().positive(), debug: z.boolean().default(false), }); type Config = z.infer<typeof ConfigSchema>; function loadConfig(path: string): Config { const content = readFileSync(path, 'utf8'); const parsed = JSON5.parse(content); return ConfigSchema.parse(parsed); // Validates at runtime } const config = loadConfig('./config.json5'); // config is fully typed AND validatedBrowser Usage
JSON5 works in all modern browsers. Here are different ways to use it client-side.
Via CDN (Quick Start)
<script src="https://unpkg.com/json5@2/dist/index.min.js"></script> <script> // JSON5 is available as a global const config = JSON5.parse(`{ theme: 'dark', sidebar: true, // Show sidebar by default }`); console.log(config.theme); // 'dark' </script>ES Module via CDN
<script type="module"> import JSON5 from 'https://unpkg.com/json5@2/dist/index.min.mjs'; const config = JSON5.parse(`{ debug: true }`); console.log(config); </script>Fetch Remote JSON5 File
async function loadRemoteConfig(url) { const response = await fetch(url); const text = await response.text(); return JSON5.parse(text); } // Usage loadRemoteConfig('/config.json5').then(config => { console.log(config); });Bundler Integration
Import JSON5 files directly in your bundled applications using loader plugins.
Vite
Vite supports JSON5 out of the box for config files. For importing JSON5 in source:
// vite.config.js import json5Plugin from 'vite-plugin-json5'; export default { plugins: [json5Plugin()], };// Now import JSON5 files directly import config from './config.json5'; console.log(config);webpack
Use the json5-loader for webpack:
npm install json5-loader --save-dev// webpack.config.js module.exports = { module: { rules: [ { test: /\.json5$/, loader: 'json5-loader', type: 'javascript/auto', }, ], }, };// Import JSON5 files import config from './config.json5';Rollup
Use @rollup/plugin-json with JSON5 parsing:
// rollup.config.js import json from '@rollup/plugin-json'; export default { plugins: [ json({ // Include JSON5 files include: ['**/*.json', '**/*.json5'], }), ], };esbuild
Create a JSON5 loader plugin:
import * as esbuild from 'esbuild'; import JSON5 from 'json5'; import { readFile } from 'fs/promises'; const json5Plugin = { name: 'json5', setup(build) { build.onLoad({ filter: /\.json5$/ }, async (args) => { const text = await readFile(args.path, 'utf8'); return { contents: JSON.stringify(JSON5.parse(text)), loader: 'json', }; }); }, }; await esbuild.build({ plugins: [json5Plugin], });Converting Between Formats
JSON5 to JSON
import JSON5 from 'json5'; const json5String = `{ // Config with comments name: 'app', debug: true, }`; // Parse JSON5, stringify as JSON const obj = JSON5.parse(json5String); const jsonString = JSON.stringify(obj, null, 2); console.log(jsonString); /* { "name": "app", "debug": true } */JSON to JSON5
import JSON5 from 'json5'; const jsonString = `{ "name": "app", "debug": true }`; // Parse JSON (or JSON5), stringify as JSON5 const obj = JSON.parse(jsonString); const json5String = JSON5.stringify(obj, null, 2); console.log(json5String); /* { name: 'app', debug: true, } */Best Practices
Use .json5 Extension
Name your files with .json5 extension for proper syntax highlighting and to signal that JSON5 features are used.
Document with Comments
Take advantage of comments to explain non-obvious settings, default values, and environment-specific configurations.
Validate Configuration
Use runtime validation (Zod, Yup, Joi) to ensure parsed configuration matches expected schema, especially for user-provided configs.
Cache Parsed Results
Parse configuration files once at startup and cache the result. Don't re-parse on every access.
Use Trailing Commas
Always include trailing commas for cleaner diffs when adding or removing items in version control.
Ready to Use JSON5?
Explore more examples or check out other language guides.