Comment-Preserving JSON/JSON5 Writer

0.2.0 · active · verified Tue Apr 21

json5-writer is a JavaScript utility designed to parse and modify JSON and JSON5 files while meticulously preserving comments, whitespace, and original formatting. Unlike typical JSON parsers that discard non-data elements, this library converts JSON5 input into a JavaScript Abstract Syntax Tree (AST) using jscodeshift, allowing programmatic updates to values without disturbing surrounding comments or formatting. It is particularly useful for configuration file management where human-readable comments are critical. The current stable version is 0.2.0. The package does not explicitly state its release cadence, but its unique AST-based approach provides fine-grained control over output, distinguishing it from simpler JSON modification tools. It supports both JSON and JSON5 syntax for input and can output standard JSON or JSON5 with configurable options for quoting and trailing commas.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart demonstrates loading, modifying, and saving a JSON5 configuration file, preserving comments and formatting. It shows how to update existing properties, add new ones, and use `undefined` to explicitly retain a property's value when writing a new object, using environment variables for dynamic values.

import * as fs from 'node:fs/promises';
import * as path from 'node:path';
import json5Writer from 'json5-writer';

async function updateConfigFile() {
  const configPath = path.join(process.cwd(), 'config.json5');
  const initialConfig = `{
  // Main application settings
  'app-name': 'My Awesome App',
  // Database connection details
  db: {
    host: 'localhost',
    port: 5432,
    user: 'admin'
  },
  // Feature flags
  features: {
    beta: true,
    analytics: false
  }
}`;

  // Ensure config file exists for demonstration
  await fs.writeFile(configPath, initialConfig, 'utf-8');

  try {
    const configContent = await fs.readFile(configPath, 'utf-8');
    const writer = json5Writer.load(configContent);

    writer.write({
      'app-name': 'New App Name',
      db: {
        host: process.env.DB_HOST ?? 'prod.database.com', // Use env var or default
        // 'port' will be preserved if not explicitly overwritten with undefined or a new value
        user: 'deploy_user' // Update user
      },
      features: {
        beta: undefined, // Preserve existing 'beta' value
        analytics: true, // Update analytics flag
        'new-feature': true // Add a new feature
      }
    });

    const updatedConfigContent = writer.toSource({
      quote: 'single',
      trailingComma: true,
      quoteKeys: undefined
    });
    console.log('Updated config.json5 content:\n', updatedConfigContent);

    await fs.writeFile(configPath, updatedConfigContent, 'utf-8');
    console.log(`Successfully updated ${configPath}`);
  } catch (error) {
    console.error(`Failed to update config file: ${error.message}`);
  }
}

updateConfigFile();

view raw JSON →