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

@ucdjs/client

v0.2.0

Published

[![npm version][npm-version-src]][npm-version-href] [![npm downloads][npm-downloads-src]][npm-downloads-href]

Readme

@ucdjs/client

npm version npm downloads

A TypeScript-first client for the UCD.js API with resource-based helpers for files, versions, version manifests, and published server configuration.

Installation

npm install @ucdjs/client

Exports

The package exports:

  • createUCDClient(baseUrl) for well-known discovery
  • createUCDClientWithConfig(baseUrl, config) for explicit endpoint configuration
  • discoverEndpointsFromConfig(baseUrl) if you want to fetch the well-known config yourself
  • getDefaultUCDEndpointConfig() for the library's built-in fallback config

Usage

Automatic discovery with createUCDClient

createUCDClient() fetches /.well-known/ucd-config.json from the provided origin, validates it, and then creates resource wrappers from the discovered endpoint paths. This function is async and will throw if discovery fails or the well-known config is invalid.

import { createUCDClient } from "@ucdjs/client";

const client = await createUCDClient("https://api.ucdjs.dev");

const { data: versions, error } = await client.versions.list();

if (error) {
  console.error("Failed to fetch versions:", error.message);
} else {
  console.log("Available versions:", versions);
}

Explicit configuration with createUCDClientWithConfig

createUCDClientWithConfig() skips the discovery request. You pass the same UCDWellKnownConfig shape that the well-known endpoint would return.

This is useful when:

  • you already have the config available at build time
  • you want to avoid an extra startup request
  • your API is hosted on a different path, but still serves the same response types
import { createUCDClientWithConfig } from "@ucdjs/client";

const client = createUCDClientWithConfig("https://example.com", {
  version: "0.1",
  endpoints: {
    files: "/custom/api/files",
    manifest: "/custom/api/versions/{version}/manifest",
    versions: "/custom/api/versions",
  },
});

const { data: fileTree, error } = await client.versions.getFileTree("16.0.0");

if (error) {
  console.error("Failed to fetch file tree:", error.message);
} else {
  console.log("File tree:", fileTree);
}

Well-known discovery vs. explicit config

The client supports two ways to arrive at the same endpoint shape:

  • createUCDClient(baseUrl) reads https://<origin>/.well-known/ucd-config.json
  • createUCDClientWithConfig(baseUrl, config) accepts that config object directly

In other words, the difference is the source of truth:

  • well-known discovery loads the config from the server at runtime
  • explicit config provides the same data in code

This makes it possible to host the API under a different path without changing the client-facing types. For example, a deployment may expose:

  • /.well-known/ucd-config.json on the main origin
  • /edge/api/files for files
  • /edge/api/versions for version endpoints

As long as the config points to those paths, the same client.files.* and client.versions.* methods continue to work.

Regardless of whether you created the client with createUCDClient() or createUCDClientWithConfig(), client.config.get() always reads the published well-known config from the origin:

  • /.well-known/ucd-config.json

Version manifest requests follow the configured endpoints.manifest value. By default that points to the canonical API route:

  • /api/v1/versions/{version}/manifest

Resources

The returned client exposes resource helpers:

  • client.files.get(path) to fetch a Unicode file or directory listing
  • client.versions.list() to list available Unicode versions
  • client.versions.getFileTree(version) to fetch a version's file tree
  • client.versions.getManifest(version) to read the canonical per-version manifest
  • client.config.get() to read /.well-known/ucd-config.json

Fetch a file

const { data: fileContent, error } = await client.files.get("16.0.0/ucd/UnicodeData.txt");

if (error) {
  console.error("Failed to fetch file:", error.message);
} else {
  console.log("File content:", fileContent);
}

Read the published config

const { data: config, error } = await client.config.get();

if (error) {
  console.error("Failed to fetch config:", error.message);
} else {
  console.log("Published config:", config);
}

Read a version manifest

const { data: manifest, error } = await client.versions.getManifest("16.0.0");

if (error) {
  console.error("Failed to fetch manifest:", error.message);
} else {
  console.log("Expected files:", manifest.expectedFiles);
}

[!NOTE] Full documentation is available at docs.ucdjs.dev/api-reference/client.

License

Published under MIT License.