PHPackages                             otar/jsonc - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Parsing &amp; Serialization](/categories/parsing)
4. /
5. otar/jsonc

ActiveLibrary[Parsing &amp; Serialization](/categories/parsing)

otar/jsonc
==========

A production-ready PHP library for parsing JSONC (JSON with Comments) format with drop-in compatibility for json\_decode()

v2.0.0(3w ago)61.5kMITPHPPHP ^8.1CI passing

Since Jan 2Pushed 3w agoCompare

[ Source](https://github.com/otar/jsonc)[ Packagist](https://packagist.org/packages/otar/jsonc)[ RSS](/packages/otar-jsonc/feed)WikiDiscussions main Synced today

READMEChangelogDependencies (4)Versions (10)Used By (0)

otar/jsonc
==========

[](#otarjsonc)

A production-ready PHP library for parsing [JSONC (JSON with Comments)](https://jsonc.org/) format with drop-in compatibility for `json_decode()`.

[![CI](https://github.com/otar/jsonc/actions/workflows/ci.yml/badge.svg)](https://github.com/otar/jsonc/actions/workflows/ci.yml)[![codecov](https://camo.githubusercontent.com/a2561e17cd4500b6953a5888d87ec5ec19521340b9e195cfedb2278806d2530b/68747470733a2f2f636f6465636f762e696f2f67682f6f7461722f6a736f6e632f6272616e63682f6d61696e2f67726170682f62616467652e737667)](https://codecov.io/gh/otar/jsonc)[![PHP Version](https://camo.githubusercontent.com/cc9cdea9aa96b40a822425e981b0a030e3371202973c7d57b74e8e99834f81dc/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d253545382e312d626c7565)](https://php.net)[![License](https://camo.githubusercontent.com/f8df3091bbe1149f398a5369b2c39e896766f9f6efba3477c63e9b4aa940ef14/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d677265656e)](LICENSE)

Features
--------

[](#features)

- **Single-line comments** (`//`) and **multi-line comments** (`/* */`)
- **Trailing commas** in objects and arrays
- **Drop-in replacement** for `json_decode()` — same signature, same error behavior, verified by a differential test suite
- **Edge case handling**: Preserves strings with comment syntax, escaped characters, Unicode
- **Strict by default**: malformed input (raw control bytes, unclosed strings or comments) is rejected like native `json_decode()` does — never silently sanitized
- **Fast**: plain JSON takes a native `json_decode()` fast path; JSONC goes through a single-pass scanner
- **Zero dependencies**: Uses native PHP JSON extension
- **Well tested**: 150+ tests with 100% code coverage, PHPStan at max level

Installation
------------

[](#installation)

```
composer require otar/jsonc
```

Usage
-----

[](#usage)

### Global Function

[](#global-function)

```
// Use global function wrapper
$data = jsonc_decode($jsonc, true);

// Check for errors using native PHP functions
if (json_last_error() !== JSON_ERROR_NONE) {
    echo json_last_error_msg();
}
```

### Basic Usage

[](#basic-usage)

```
use Otar\JSONC;

$jsonc = '{
    // This is a comment
    "name": "John Doe",
    "age": 30,
    "hobbies": [
        "reading",
        "coding", // Inline comment
    ],
}';

$data = JSONC::decode($jsonc, true);
// ['name' => 'John Doe', 'age' => 30, 'hobbies' => ['reading', 'coding']]
```

### Parse to JSON String

[](#parse-to-json-string)

```
use Otar\JSONC;

$jsonc = '{/* comment */"key": "value",}';
$json = JSONC::parse($jsonc);
// '{ "key": "value"}' — comments become a space, trailing commas are dropped

// Now you can use with standard json_decode
$data = json_decode($json, true);
```

API Reference
-------------

[](#api-reference)

### `JSONC::decode()`

[](#jsoncdecode)

Decodes a JSONC string. Drop-in replacement for `json_decode()`.

```
public static function decode(
    string $jsonc,
    ?bool $associative = null,
    int $depth = 512,
    int $flags = 0
): mixed
```

### `JSONC::parse()`

[](#jsoncparse)

Parses JSONC string and returns cleaned JSON string (without comments and trailing commas).

```
public static function parse(string $jsonc): string
```

Throws `Otar\JsoncSyntaxException` when the input ends inside an unclosed string literal or block comment — it never returns invalid JSON.

### `jsonc_decode()`

[](#jsonc_decode)

Global function alias for `JSONC::decode()`.

Error Handling
--------------

[](#error-handling)

`decode()` follows `json_decode()` exactly: invalid input returns `null` and sets the native error state.

```
$invalidJsonc = '{invalid json}';
$result = JSONC::decode($invalidJsonc);

if ($result === null && json_last_error() !== JSON_ERROR_NONE) {
    echo 'Parse error: ' . json_last_error_msg();
}
```

With `JSON_THROW_ON_ERROR` it throws instead. Unclosed JSONC constructs surface as `Otar\JsoncSyntaxException` — a `JsonException` subclass that reports where the construct opened:

```
use Otar\JsoncSyntaxException;

try {
    JSONC::decode('{"a": 1, /* unterminated', flags: JSON_THROW_ON_ERROR);
} catch (JsoncSyntaxException $e) {
    echo $e->getMessage(); // Unclosed block comment starting at offset 9
    $e->getOffset();       // 9
} catch (JsonException $e) {
    // any other JSON syntax error
}
```

`JSONC::parse()` always throws `JsoncSyntaxException` for unclosed constructs, with or without flags.

### Differences from `json_decode()`

[](#differences-from-json_decode)

- A leading UTF-8 BOM is tolerated and stripped (native `json_decode()` rejects it) — JSONC config files frequently carry one.
- Comments and trailing commas are accepted.
- Everything else matches native behavior, including `json_last_error()` codes.
- `json_last_error()` is only meaningful after `decode()`; `parse()` may probe the input internally, which writes the global JSON error state.

Requirements
------------

[](#requirements)

- PHP 8.1 or higher
- JSON extension (enabled by default in PHP)

Testing
-------

[](#testing)

```
# Run tests
composer test

# Run tests with coverage
composer test-coverage

# Static analysis (PHPStan, level max)
composer phpstan

# Micro-benchmark
composer bench
```

License
-------

[](#license)

MIT License - see [LICENSE](LICENSE) file for details.

Contributing
------------

[](#contributing)

Contributions are welcome! Please ensure all tests pass (`composer test`) and maintain code coverage.

Credits &amp; Related Projects
------------------------------

[](#credits--related-projects)

Inspired by existing JSONC parsers and the need for a robust, production-ready PHP implementation with proper edge case handling.

- [microsoft/node-jsonc-parser](https://github.com/microsoft/node-jsonc-parser) - Official JSONC parser for Node.js
- [VS Code](https://code.visualstudio.com/) - Uses JSONC for configuration files

###  Health Score

47

—

FairBetter than 93% of packages

Maintenance95

Actively maintained with recent releases

Popularity26

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity49

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~20 days

Recently: every ~14 days

Total

9

Last Release

24d ago

Major Versions

v1.3.0 → v2.0.02026-06-11

PHP version history (2 changes)v1.0.0PHP ^8.0

v1.1.2PHP ^8.1

### Community

Maintainers

![](https://www.gravatar.com/avatar/d694e82e8052c528194bd669c115d182b4e4209dce7a506e32fa7e78c6e7ede2?d=identicon)[otar](/maintainers/otar)

---

Top Contributors

[![otar](https://avatars.githubusercontent.com/u/97141?v=4)](https://github.com/otar "otar (27 commits)")

---

Tags

commacommentsjsonjsoncphpjsonconfigurationconfigparsercommentsdecoderjsonctrailing-commas

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/otar-jsonc/health.svg)

```
[![Health](https://phpackages.com/badges/otar-jsonc/health.svg)](https://phpackages.com/packages/otar-jsonc)
```

###  Alternatives

[hassankhan/config

Lightweight configuration file loader that supports PHP, INI, XML, JSON, and YAML files

1.0k13.8M187](/packages/hassankhan-config)[laktak/hjson

JSON for Humans. A configuration file format with relaxed syntax, fewer mistakes and more comments.

86245.3k14](/packages/laktak-hjson)[m1/vars

Vars is a simple to use and easily extendable configuration loader with in built loaders for ini, json, PHP, toml, XML and yaml/yml file types. It also comes with in built support for Silex and more frameworks to come soon.

64124.3k1](/packages/m1-vars)[sbsaga/toon

🧠 TOON for Laravel — a compact, human-readable, and token-efficient data format for AI prompts &amp; LLM contexts. Perfect for ChatGPT, Gemini, Claude, Mistral, and OpenAI integrations (JSON ⇄ TOON).

6753.8k](/packages/sbsaga-toon)[romanpitak/nginx-config-processor

Nginx configuration files processor.

6935.9k1](/packages/romanpitak-nginx-config-processor)[thewunder/conphigure

Framework Agnostic Configuration Library

3120.6k](/packages/thewunder-conphigure)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
