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

json-storage-formatter

v3.0.3

Published

Package for json stringify objects without losing data types

Readme

json-storage-formatter 🌟


🎯 The Problem

const userProfile = {
  id: 42,
  createdAt: new Date('2024-10-01T10:30:00Z'),
  preferences: new Map([
    ['theme', 'dark'],
    ['languages', new Set(['en', 'es'])],
  ]),
};

console.log(JSON.stringify(userProfile, null, 2));

Console Output:

{
  "id": 42,
  "createdAt": "2024-10-01T10:30:00.000Z",
  "preferences": {}
}

JSON.stringify loses all type information for Dates, Maps, Sets, RegExps, and more. Your data is flattened, and restoring it is impossible.



🚀 Why Use This Library?

🟢 Quick Start

Instantly Store and Restore Complex Data

import { formatToStore, formatFromStore } from 'json-storage-formatter';

// Imagine you want to save this to localStorage, a URL, or a DB:
const userProfile = {
  id: 42,
  createdAt: new Date('2024-10-01T10:30:00Z'),
  preferences: new Map([
    ['theme', 'dark'],
    ['languages', new Set(['en', 'es'])],
  ]),
};

// Serialize for storage (preserves all types!)
const stored = formatToStore(userProfile);
localStorage.setItem('profile', stored);

// ...later, or in another environment:
const loaded = localStorage.getItem('profile');
const restored = formatFromStore<typeof userProfile>(loaded);

// restored.createdAt is a Date
// restored.preferences is a Map with a Set inside

// Works for any structure: deeply nested, with Dates, Sets, Maps, RegExps, Errors, undefined, NaN, etc.


🟣 Complex Types Example

const complex = {
  date: new Date('2024-10-01T10:30:00Z'),
  set: new Set(['a', 'b']),
  map: new Map([
    ['x', 1],
    ['y', 2],
  ]),
  regex: /abc/i,
  error: new Error('fail'),
  undef: undefined,
  nan: NaN,
  inf: Infinity,
};

const stored = formatToStore(complex);
const restored = formatFromStore<typeof complex>(stored);
// All types are preserved!

🔒 Type-Safe Storage

Store and restore Maps, Sets, Dates, RegExps, Errors, and more — not just plain objects.

import { formatToStore, formatFromStore } from 'json-storage-formatter';

const original = new Map([
  ['created', new Date('2024-10-01T10:30:00Z')],
  ['tags', new Set(['a', 'b'])],
]);

const json = formatToStore(original); // string for storage
const restored = formatFromStore<Map<string, unknown>>(json);

⚡ No Boilerplate

Just call formatToStore before saving, and formatFromStore when loading. No config, no setup, no custom revivers.

localStorage.setItem('profile', formatToStore(profile));
const profile = formatFromStore(localStorage.getItem('profile'));

🛠️ How It Works

formatToStore adds a tiny type marker to every special value:

{
  "$t": "map",
  "$v": [["key", { "$t": "date", "$v": "2024-10-01T10:30:00.000Z" }]]
}

When you call formatFromStore, it reads those markers and reconstructs the original types — even deeply nested.


✨ Real-World Examples

1️⃣ React: Syncing Complex State to localStorage

import { useState } from 'react';
import { formatToStore, formatFromStore } from 'json-storage-formatter';

type WidgetConfig = { location: string; units: string };
type DashboardConfig = {
  theme: 'light' | 'dark' | 'system';
  widgets: Map<string, WidgetConfig>;
  hiddenWidgets: Set<string>;
  lastCustomizedAt: Date;
};

function useDashboardConfig() {
  const [config, setConfig] = useState<DashboardConfig>(() => {
    const json = localStorage.getItem('dashboard-config');
    return json ? formatFromStore<DashboardConfig>(json) : getDefaultDashboardConfig();
  });

  const saveConfig = (newConfig: DashboardConfig) => {
    localStorage.setItem('dashboard-config', formatToStore(newConfig));
    setConfig(newConfig);
  };

  return { config, saveConfig };
}

// Usage
const example: DashboardConfig = {
  theme: 'dark',
  widgets: new Map([
    ['weather', { location: 'New York', units: 'metric' }],
    ['stocks', { location: 'NASDAQ', units: 'USD' }],
  ]),
  hiddenWidgets: new Set(['news']),
  lastCustomizedAt: new Date(),
};

2️⃣ React: Syncing Filters via URL (Shareable Dashboard Queries)

import { useState } from 'react';
import { formatToStore, formatFromStore } from 'json-storage-formatter';

type DashboardQuery = {
  dateRange: { from: Date; to: Date };
  selectedCategories: Set<string>;
  additionalSettings: Map<string, unknown>;
};

function useUrlQuery() {
  const [query, setQuery] = useState<DashboardQuery>(() => {
    const params = new URLSearchParams(window.location.search);
    const storedQuery = params.get('query');
    return storedQuery ? formatFromStore<DashboardQuery>(atob(storedQuery)) : getDefaultDashboardQuery();
  });

  const updateQuery = (newQuery: DashboardQuery) => {
    const encoded = btoa(formatToStore(newQuery));
    window.history.replaceState(null, '', `${window.location.pathname}?query=${encoded}`);
    setQuery(newQuery);
  };

  return { query, updateQuery };
}

3️⃣ Framework-Agnostic: Node.js/Backend Example

// Save and load any structure in Redis, PostgreSQL, or files
const { formatToStore, formatFromStore } = require('json-storage-formatter');

const session = {
  userId: 123,
  expires: new Date(),
  permissions: new Set(['read', 'write']),
};

// Store in Redis
redis.set('session:123', formatToStore(session));

// Later...
const raw = await redis.get('session:123');
const restored = formatFromStore(raw);
// restored.expires is a Date, restored.permissions is a Set

🧩 Supported Types

| Type | Supported? | Restored As | | ------------ | ---------- | --------------- | | Date | ✅ | Date | | Set | ✅ | Set | | Map | ✅ | Map | | RegExp | ✅ | RegExp | | Error | ✅ | Error | | undefined | ✅ | undefined | | NaN/Infinity | ✅ | number | | Function | ❌ | (not supported) |


🧰 Utility Functions

| Function | Description | Example | | ------------- | ---------------------------------------- | ----------------------------- | | isNil | Checks if value is null or undefined | isNil(null); // true | | isNumber | Checks if value is a number | isNumber(42); // true | | isBoolean | Checks if value is a boolean | isBoolean(false); // true | | isString | Checks if value is a string | isString('hi'); // true | | isDate | Checks if value is a Date | isDate(new Date()); // true |


⚖️ Comparison

| Behavior | JSON.stringify | json-storage-formatter | | ------------- | --------------- | ------------------------ | | Date | Becomes string | ✅ Restored as Date | | Set | Lost completely | ✅ Restored as Set | | Map | Lost completely | ✅ Restored as Map | | Undefined | Omitted | ✅ Restored as undefined | | Regexp | Lost completely | ✅ Restored as RegExp | | Error | Lost completely | ✅ Restored as Error |


📦 Installation

npm install json-storage-formatter
yarn add json-storage-formatter

📝 API Reference

formatToStore(value)

Converts any value into a JSON-safe string with type metadata.

formatFromStore(string)

Restores the serialized string back to its original types.


💡 Pro Tips

  • Use with any storage: localStorage, sessionStorage, AsyncStorage, Redis, PostgreSQL JSON columns, URLs, etc.
  • Works with deeply nested structures.
  • Framework-agnostic: use in React, Node.js, or vanilla JS/TS.