JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 6
  • Score
    100M100P100Q34441F
  • License MIT

JSON, handled. Safe parse, stringify, format, validate.

Package Exports

  • handlejson

Readme

handlejson

JSON, handled. Safe parse, stringify, format, validate.

Install

npm install handlejson

Quick Start

import { parse, stringify } from 'handlejson'

const data = parse('{"name":"John"}')  // { name: 'John' }
const json = stringify({ name: 'John' })  // '{"name":"John"}'

Why?

JSON.parse and JSON.stringify throw errors. You always need try-catch. This gets old.

Before:

let data
try {
  data = JSON.parse(str)
} catch {
  data = null
}

After:

import { parse } from 'handlejson'

const data = parse(str) // null if invalid

Features

  • Safe parse with default values
  • Safe stringify with circular reference handling
  • Validation without parsing twice
  • Pretty-print and minify
  • TypeScript-first
  • Zero dependencies
  • ~1KB gzipped

Usage

Safe Parse

import { parse } from 'handlejson'

parse('{"a":1}')           // { a: 1 }
parse('invalid')           // null
parse('invalid', { default: {} })  // {}

// With reviver
parse('{"date":"2023-01-01"}', {
  reviver: (key, value) => key === 'date' ? new Date(value) : value
})

Typed Parse

type User = { name: string; age: number }

const user = parse<User>('{"name":"John","age":30}')
// user is User | null

Safe Stringify

import { stringify } from 'handlejson'

stringify({ a: 1 })  // '{"a":1}'

// Handles circular refs
const obj = { a: 1 }
obj.self = obj
stringify(obj)  // '{"a":1,"self":"[Circular]"}'

Error Handling

Get error details instead of just null:

import { tryParse, tryStringify } from 'handlejson'

const [data, error] = tryParse(str)
if (error) {
  console.log('Parse failed:', error.message)
}

const [json, err] = tryStringify(obj)
const [json2, err2] = tryStringify(obj, { space: 2 })

Validation

import { isValid } from 'handlejson'

isValid('{"a":1}')  // true
isValid('invalid')  // false
isValid('{a:1}')    // false

Format (Pretty-print)

import { format } from 'handlejson'

format({ a: 1 })      // '{\n  "a": 1\n}'
format({ a: 1 }, 4)   // 4-space indent
format('{"a":1}')     // works with strings too

Minify

import { minify } from 'handlejson'

minify({ a: 1, b: 2 })              // '{"a":1,"b":2}'
minify('{\n  "a": 1\n}')            // '{"a":1}'

Common Use Cases

API responses:

const response = await fetch('/api/user')
const user = parse(await response.text(), { default: {} })

LocalStorage:

const saved = parse(localStorage.getItem('data'), { default: null })

API

Function Description
parse(str, options?) Safe parse, returns null on error. Options: default, reviver
stringify(value, options?) Safe stringify, handles circular refs. Options: space, replacer
tryParse(str, reviver?) Returns [result, error] tuple
tryStringify(value, options?) Returns [result, error] tuple. Options: space, replacer
isValid(str) Check if string is valid JSON
format(value, space?) Pretty-print with indentation
minify(value) Remove all whitespace

Date Handling

Need to convert date strings? Use a reviver:

parse('{"createdAt":"2023-01-01T10:00:00Z"}', {
  reviver: (key, value) => {
    if (key.endsWith('At') && typeof value === 'string') {
      const date = new Date(value)
      return isNaN(date.getTime()) ? value : date
    }
    return value
  }
})

Works with ISO 8601 and Unix timestamps. Other formats need custom handling.

License

MIT