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

@okutils/json-d

v26.9.22

Published

JSON data types for TypeScript.

Readme

@okutils/json-d

General-purpose JSON types for TypeScript. Use them for API data, configuration, and other JSON data in frontend and Node.js projects when you don’t need to define the exact shape of an object. Unlike Record<string, any>, these types limit values to JSON-compatible types, including nested objects and arrays.

Installation

npm i @okutils/json-d

Usage

This is a types-only package, so use import type:

Defining a JSON Object

import type { JSONObject } from "@okutils/json-d";

const user: JSONObject = {
  id: 1,
  name: "Xiaoming",
  active: true,
  avatar: null,
  tags: ["TypeScript", "React"],
  profile: {
    city: "Shanghai",
    settings: { darkMode: true },
  },
};

Reading Object Fields

import type { JSONObject } from "@okutils/json-d";

const getDisplayName = (user: JSONObject): string => {
  const name = user.name;
  return typeof name === "string" ? name.toUpperCase() : "Anonymous user";
};

getDisplayName({ name: "Alice" }); // "ALICE"
getDisplayName({ id: 1 }); // "Anonymous user"

Fetching API Data in React

This example fetches a JSON object from /api/user.

import { useEffect, useState } from "react";
import type { JSONObject } from "@okutils/json-d";

export const Foo = () => {
  const [data, setData] = useState<JSONObject | null>(null);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    const controller = new AbortController();

    const fetchData = async () => {
      try {
        const response = await fetch("/api/user", {
          signal: controller.signal,
        });

        if (!response.ok) {
          throw new Error(`Request failed: ${response.status}`);
        }

        const value: unknown = await response.json();

        // A JSON response can also be an array, a scalar, or null.
        if (
          value === null ||
          typeof value !== "object" ||
          Array.isArray(value)
        ) {
          throw new Error("Expected a JSON object from the API");
        }

        if (!controller.signal.aborted) {
          setData(value as JSONObject);
        }
      } catch (error) {
        if (!controller.signal.aborted) {
          setError(error instanceof Error ? error.message : "Request failed");
        }
      }
    };

    void fetchData();

    return () => controller.abort();
  }, []);

  if (error !== null) return <p role="alert">{error}</p>;
  if (data === null) return <p>Loading…</p>;

  const name = typeof data.name === "string" ? data.name : "Anonymous user";

  return (
    <section>
      <h2>{name}</h2>
      <pre>{JSON.stringify(data, null, 2)}</pre>
    </section>
  );
};

Advanced Usage

Working with JSONScalar

Use JSONScalar for values that can be strings, numbers, booleans, or null:

import type { JSONScalar } from "@okutils/json-d";

const formatCell = (value: JSONScalar): string => {
  if (value === null) return "—";
  if (typeof value === "boolean") return value ? "Yes" : "No";
  return String(value);
};

formatCell("Xiaoming"); // "Xiaoming"
formatCell(42); // "42"
formatCell(false); // "No"
formatCell(null); // "—"

// formatCell({ name: 'Xiaoming' }); // Type error: objects are not allowed
// formatCell(['TypeScript']); // Type error: arrays are not allowed

Working with JSONValue

Use JSONValue when your data can be any JSON value: a scalar, an object, or an array. For example, this browser utility saves JSON data to localStorage:

import type { JSONValue } from "@okutils/json-d";

const saveJSON = (key: string, value: JSONValue): void => {
  localStorage.setItem(key, JSON.stringify(value));
};

saveJSON("theme", "dark");
saveJSON("pageSize", 20);
saveJSON("notifications", true);
saveJSON("selection", null);
saveJSON("user", { id: 1, name: "Xiaoming" });
saveJSON("recentUsers", [
  { id: 1, name: "Xiaoming" },
  { id: 2, name: "Xiaohong" },
]);

// Readonly arrays are supported too, including those created with `as const`.
saveJSON("coordinates", [121.47, 31.23] as const);