npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

mathers

v1.0.0

Published

Go-compatible JSON encoder - byte-for-byte compatible with encoding/json.Marshal

Readme

mathers

CI codecov npm version License: MIT Node.js

Perfect Go-compatible JSON encoder with type-driven behavior that mirrors Go's encoding/json.Marshal exactly.

Overview

mathers provides byte-for-byte compatibility with Go's JSON marshaling by implementing type-driven behavior that distinguishes between Go structs and Go maps. This fundamental distinction allows JavaScript developers to produce identical JSON output to their Go counterparts.

Key Innovation: Type-Driven JSON Marshaling

Just as Go treats structs and maps differently during JSON marshaling, mathers provides distinct JavaScript constructs:

  • Plain objects → Go struct behavior (preserve field order)
  • map() function → Go map behavior (sort keys alphabetically)
  • ES6 Maps → Go map behavior (sort keys alphabetically)

Installation

npm install mathers

Quick Start

import { marshal, map } from 'mathers';

// Plain objects preserve insertion order (Go struct behavior)
const person = { id: 1, name: "Alice", age: 30 };
marshal(person); // {"id":1,"name":"Alice","age":30}

// map() function sorts keys alphabetically (Go map behavior)
const settings = map({ zebra: "last", alpha: "first", beta: "middle" });
marshal(settings); // {"alpha":"first","beta":"middle","zebra":"last"}

API Reference

Functions

marshal(value: GoJSON): string

Encodes a JavaScript value to Go-compatible JSON string with type-driven behavior.

Parameters:

  • value: GoJSON - The value to encode

Returns:

  • string - JSON string that is byte-for-byte compatible with Go's encoding/json.Marshal

Examples:

import { marshal } from 'mathers';

// Struct-like data (preserves order)
marshal({ name: "Alice", age: 30 });
// → '{"name":"Alice","age":30}'

// Array data
marshal([1, 2, 3]);
// → '[1,2,3]'

map(obj: Record<string, GoJSON>): GoMap

Creates a map object that will have its keys sorted alphabetically during marshaling.

Parameters:

  • obj: Record<string, GoJSON> - Plain object to convert to sortable map

Returns:

  • GoMap - Object that marshals with alphabetically sorted keys

Examples:

import { marshal, map } from 'mathers';

// Create map with sorted keys
const config = map({
  database: "postgres",
  cache: "redis", 
  queue: "rabbitmq"
});

marshal(config);
// → '{"cache":"redis","database":"postgres","queue":"rabbitmq"}'

Type Definitions

export type GoJSON =
  | null
  | boolean
  | number
  | string
  | GoJSON[]
  | GoMap;

export interface GoMap {
  readonly [k: string]: GoJSON;
}

Go Struct vs Map Behavior

Go Struct Behavior (Plain Objects)

Plain JavaScript objects preserve their field insertion order, matching how Go marshals struct fields:

// Go equivalent: type Person struct { ID int; Name string; Age int }
const person = {
  id: 1,
  name: "Alice", 
  age: 30
};

marshal(person); // {"id":1,"name":"Alice","age":30}
// Preserves declaration order like Go structs

Go Map Behavior (Sorted Keys)

Use map() function or ES6 Maps for sorted keys, matching Go's map[string]T behavior:

map() Function Objects

// Go equivalent: map[string]string{"zebra": "last", "alpha": "first"}
const settings = map({
  zebra: "last",
  alpha: "first", 
  beta: "middle"
});

marshal(settings); // {"alpha":"first","beta":"middle","zebra":"last"}

ES6 Maps

const userRoles = new Map([
  ["zebra", "admin"],
  ["alpha", "user"],
  ["beta", "guest"]
]);

marshal(userRoles); // {"alpha":"user","beta":"guest","zebra":"admin"}

Error Handling

mathers enforces strict Go compatibility by rejecting invalid inputs:

// Invalid numbers (Go rejects these)
marshal(NaN);        // Error: NaN/Infinity not supported by Go JSON
marshal(Infinity);   // Error: NaN/Infinity not supported by Go JSON

// Undefined values (Go omits these)
marshal({ key: undefined }); // Error: Undefined value for key: key

// Unsupported types
marshal(Symbol('test')); // Error: Unsupported type: symbol

HTML Safety and Character Escaping

mathers escapes characters exactly like Go for security and compatibility:

const htmlContent = {
  script: '<script>alert("XSS")</script>',
  html: '<div>Content & more</div>'
};

marshal(htmlContent);
// {"script":"\u003cscript\u003ealert(\"XSS\")\u003c/script\u003e","html":"\u003cdiv\u003eContent \u0026 more\u003c/div\u003e"}

Escaped Characters:

  • HTML: <\u003c, >\u003e, &\u0026
  • Control: \b, \f, \n, \r, \t
  • Unicode line separators: \u2028, \u2029
  • Special: "\", \\\

Go Compatibility Verification

This library maintains byte-for-byte compatibility with Go's encoding/json.Marshal through:

Verification Process

  1. Go test generation: 36 test files created by actual Go code
  2. Automated comparison: Every output compared against Go's output
  3. Edge case coverage: Special numbers, Unicode, HTML, deep nesting
  4. Continuous testing: CI runs Go compatibility tests on every change

Compatibility Features

| Feature | mathers | Go json.Marshal | |---------|---------|-------------------| | Struct field order | Preserved | Preserved | | Map key order | Alphabetically sorted | Alphabetically sorted | | HTML escaping | \u003c, \u003e, \u0026 | \u003c, \u003e, \u0026 | | Negative zero | Preserved as -0 | Preserved as -0 | | NaN/Infinity | Throws error | Returns error | | Compact output | No spaces | No spaces |

Running Verification

# Generate Go test vectors
cd test && go run generate-test-files.go

# Run compatibility tests
npm test test/go-file-comparison.test.ts

Comparison with Standard JSON

| Feature | mathers | JSON.stringify | |---------|-----------|------------------| | Object key order | Type-driven (preserve/sort) | Insertion order | | Map support | Native ES6 Map support | Requires replacer function | | HTML safety | Always escaped | No escaping | | Invalid numbers | Throws error | Converts to null | | Undefined handling | Throws error | Omits or null | | Go compatibility | Byte-for-byte identical | Different output |

Development

Prerequisites

  • Node.js 18+
  • Go 1.19+ (for compatibility testing)

Setup

# Install dependencies
npm install

# Build the library
npm run build

# Run tests with coverage
npm run test:coverage

# Run mutation testing (85%+ required)
npm run test:mutation

# Full verification pipeline
npm run verify

Testing Standards

  • 100% line coverage maintained
  • 85%+ mutation testing score required
  • Property-based testing with fast-check
  • Go compatibility tests for every release

Verification Commands

# Generate Go test vectors
cd test && go run generate-test-files.go

# Verify against Go output
npm test test/go-file-comparison.test.ts

# Full verification pipeline
npm run verify

Contributing

We welcome contributions! Please ensure:

  1. All tests pass: npm run verify
  2. Coverage maintained: 100% line coverage required
  3. Go compatibility: All compatibility tests must pass
  4. Ultra-descriptive naming: No abbreviations
  5. Exhaustive testing: Property-based and edge case testing

Code Standards

// ✅ Ultra-descriptive names
function encodeGoCompatibleJSON(value: GoJSON): string
const shouldSortObjectKeysAlphabetically = true;

// ❌ Abbreviations and unclear names  
function encode(val: any): string
const sort = true;

Development Philosophy

mathers follows strict empirical engineering principles:

  • Ultra-descriptive names - No abbreviations
  • Exhaustive testing - Every change must increase or maintain coverage
  • Go compatibility - All outputs must match Go's encoding/json.Marshal exactly
  • Type safety - Full TypeScript strict mode compliance

Changelog

[1.0.0] - 2024-01-15

Added:

  • Type-driven JSON marshaling with distinct behavior for Go structs vs maps
  • marshal(value) function for Go-compatible JSON encoding
  • map(obj) function for creating objects with sorted keys
  • Full ES6 Map support with automatic key sorting
  • Byte-for-byte Go compatibility verified against encoding/json.Marshal
  • Comprehensive error handling matching Go's validation rules
  • HTML safety with proper character escaping
  • TypeScript support with strict type checking
  • Zero-dependency implementation

Security:

  • Fixed null options parameter vulnerability
  • XSS prevention through HTML character escaping
  • Safe handling of undefined values with clear error messages

Testing:

  • 100% line coverage maintained
  • 85%+ mutation testing score
  • 36 Go compatibility test files generated and verified
  • 170+ total tests covering all functionality

License

MIT

Why "mathers"?

Named after Marshal mathers (Eminem), because this library marshals data with the precision and attention to detail of a master craftsman. Just as the artist's lyrics are meticulously structured, this encoder ensures every byte matches Go's output exactly.