JSON5 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 json5

Yarn

yarn add json5

pnpm

pnpm add json5

Bun

bun add json5

65M+

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); // true

JSON5.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 number

Type-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 typed

With 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 validated

Browser 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.