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

@joy-loyalty/sdk

v0.3.0

Published

Isomorphic client for the Joy Loyalty Headless API (docs/api/feat-headless-v1.yaml)

Readme

@joy-loyalty/sdk

Isomorphic TypeScript client for the Joy Loyalty Headless API. Use it directly in custom storefronts, or indirectly through @joy-loyalty/hydrogen and @joy-loyalty/weaverse-hydrogen.

ESM-only. Web-standard globals only (fetch, URL, URLSearchParams), so it runs in browsers, Oxygen workers and React Native.

Prerequisites

A Joy Loyalty store on the Ultimate plan (the Headless API is plan-gated).

Install

npm install @joy-loyalty/sdk

Entry points

| Import | Purpose | |---|---| | @joy-loyalty/sdk | Shared types and JoyApiError only (no runtime clients). | | @joy-loyalty/sdk/server | createJoyServerClient — public, shop-scoped GETs for SSR loaders (getPrograms, getTiers, getShopConfig, place-order scope). | | @joy-loyalty/sdk/client | createJoyClient / Joy — Bearer-JWT /customer/* calls from the browser or native. | | @joy-loyalty/sdk/ports, /widget-contracts, /loyalty-page-contracts, /headless-loyalty-page-client, /host | Contracts and host plumbing used by @joy-loyalty/hydrogen. Most apps do not need these directly. |

Usage

Server (loader):

import {createJoyServerClient} from '@joy-loyalty/sdk/server';

const joy = createJoyServerClient({
  apiUrl: env.JOY_API_URL,          // https://api.joy.so/app/api/v1/headless
  shopDomain: env.JOY_SHOP_DOMAIN,
  locale: storefront.i18n.language.toLowerCase()
});
const [programs, tiers, config] = await Promise.all([joy.getPrograms(), joy.getTiers(), joy.getShopConfig()]);

Client (browser/native). The SDK never stores the token; you hand it in and supply a refresher:

import {createJoyClient} from '@joy-loyalty/sdk/client';

const client = createJoyClient({
  apiUrl,
  shopDomain,
  token,                            // customer JWT, or null for a guest
  onTokenExpired: async () => fetchFreshToken()   // called once on 401, then the request is retried
});

Errors are thrown as JoyApiError.

Obtaining a customer token

Customer JWTs are minted by exchanging a server-signed grant at POST {apiUrl}/auth/token. That requires the headless API secret from your Joy admin, so it must happen on your server (@joy-loyalty/hydrogen/routes/joy-token does this for Hydrogen).

Warning: server-only secret. JOY_API_SECRET must only be read on the server. Never prefix it PUBLIC_ or VITE_, and never import code that reads it into a client bundle. @joy-loyalty/sdk/client never needs the secret. The secret will be rotated to a dedicated headless secret before general availability.

Security notes

The customer JWT is short-lived (about 1 hour). If you keep it in browser storage (as @joy-loyalty/hydrogen does, in sessionStorage), XSS on your origin can read it, so keep a strict CSP.

License

Proprietary. Copyright (c) 2026 Avada Group. All rights reserved. Licensed only for use with the Joy Loyalty service under the Joy Loyalty Terms of Service. See LICENSE.