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

@uploadcare/cname-prefix

v6.21.0

Published

Helpers for working with Uploadcare CNAME-prefixed URLs, with a native-crypto build for Node.

Readme

Uploadcare CNAME Prefix

This package provides a helper for working with Uploadcare CDN CNAME prefixes.

API Reference

Build Status NPM version GitHub release Uploadcare stack on StackShare

Install

npm install @uploadcare/cname-prefix

Usage

The package builds a subdomain-based (prefixed) CDN base from your public key. Two variants return the same string; they differ only in where the SHA-256 comes from.

import {
  getPrefixedCdnBaseAsync,
  getPrefixedCdnBaseSync
} from '@uploadcare/cname-prefix'

await getPrefixedCdnBaseAsync('demopublickey', 'https://ucarecd.net')
// 'https://1s4oyld5dc.ucarecd.net'

getPrefixedCdnBaseSync('demopublickey', 'https://ucarecd.net')
// 'https://1s4oyld5dc.ucarecd.net'

Use isPrefixedCdnBase(cdnBase, base) to check whether a base is already prefixed. Whichever variant you pick, the answer never changes for a given public key, so resolve it once at startup and keep the string instead of recomputing it for every URL.

Which one to use

| Runtime | Use | Why | | ----------------------------- | -------- | ---------------------------------------------------------- | | Browser, Web/Service Worker | …Async | WebCrypto is already there, so nothing is bundled | | Browser, when you can't await | …Sync | works, and carries a SHA-256 with it (about a kilobyte) | | Node.js (server code) | …Sync | node:crypto is native and synchronous — no Promise | | Node.js (isomorphic code) | …Async | works too: WebCrypto via node:crypto, no runtime branch | | React Native | …Sync | no WebCrypto in Hermes; the portable build is the only one |

In a browser, prefer the async variant. It calls crypto.subtle.digest, the platform's own implementation, so the digest adds nothing to your bundle. It needs a secure context, HTTPS or localhost; on a plain http:// origin crypto.subtle is undefined and the call fails.

Use the sync variant when a Promise would infect the call site, such as a config module's top-level export or a synchronous render path. It works in a browser and costs you the SHA-256 it carries, about a kilobyte.

On Node, prefer the sync variant. The node export condition, which Node.js, Vitest and bundlers targeting Node all resolve, swaps in a build backed by node:crypto, so the portable SHA-256 never reaches a server bundle. Your import stays the same, and the digest is native and synchronous — no Promise to await.

The async variant works on Node too. Under the same node condition it takes WebCrypto from node:crypto rather than the global scope, and returns the same string the sync one does. Reach for it only to keep a single code path across browser and server: isomorphic or SSR code that already awaits getPrefixedCdnBaseAsync no longer has to branch on the runtime, and no createHash reaches the call path.

On React Native, use the sync variant too. The react-native condition resolves to the portable build, which is the only one that can run there: Hermes has neither crypto.subtle nor node:crypto. It needs TextEncoder, which Hermes provides from React Native 0.74 and Expo SDK 51. On anything older, add a polyfill.

Node version compatibility

Both variants run on every Node the package supports (engines: node >=16), and neither needs a flag:

| API | Backed by | Available since | | -------- | -------------------------- | --------------- | | …Sync | node:crypto createHash | Node 0.x | | …Async | node:crypto webcrypto | Node 15.0.0 |

The async build reads WebCrypto from node:crypto (its webcrypto export), not from globalThis.crypto. So it does not depend on the global crypto object — which became available by default only in Node 19 — and needs no --experimental-global-webcrypto flag. On every version this package targets, both APIs are present.

What it costs

Marginal cost of the helper, esbuild --minify over the published build:

| Import | min | gzip | brotli | | --------------------------------------- | ------ | ------ | ---------- | | /async in a browser | 413 B | 314 B | 269 B | | /sync in a browser or React Native | 1812 B | 1111 B | 968 B | | /sync on Node (node:crypto) | 290 B | 249 B | 209 B | | both, from the root entry, in a browser | 2082 B | 1247 B | 1081 B |

Brotli is the column to read, since that is what a CDN serves. In a browser the async variant costs about a quarter of the sync one. On Node the numbers change: the digest is node:crypto, external to the bundle, so the async variant is a few hundred bytes there too — about the same as /sync on Node above, not the kilobyte the portable sync build costs in a browser. Size is not the deciding factor on Node; pick …Sync to avoid a Promise, …Async to share code with the browser.

Entry points

| Import | Contains | | -------------------------------- | ------------------------------------- | | @uploadcare/cname-prefix | both variants and isPrefixedCdnBase | | @uploadcare/cname-prefix/async | the async variant only | | @uploadcare/cname-prefix/sync | the sync variant only |

Import a subpath to keep the other variant out of the bundle. Each subpath carries node and react-native conditions, so your bundler or runtime picks the implementation: the native digest on Node, the portable one on React Native.

Security issues

If you think you ran into something in Uploadcare libraries that might have security implications, please hit us up at [email protected] or Hackerone.

We'll contact you personally in a short time to fix an issue through co-op and prior to any public disclosure.

Feedback

Issues and PRs are welcome. You can provide your feedback or drop us a support request at [email protected].