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

@emergente-labs/elements-sdk

v0.1.0

Published

Embeddable payment Elements SDK for moneymotion.

Readme

@emergente-labs/elements-sdk

Embeddable, processor-agnostic payment Elements for the browser. Mount Card, Express Checkout, or Address iframes on your page, collect a buyer's payment details, and run a full PaymentIntent confirmation — including 3-D Secure — without ever touching the card data yourself.

The SDK ships two interchangeable surfaces:

  • Promise API (@emergente-labs/elements-sdk) — a class-based facade for vanilla JS, React, Vue, etc.
  • Effect API (@emergente-labs/elements-sdk/effect) — Effect-native primitives for codebases already running an Effect runtime.

Both surfaces share the same internals; the Promise wrapper is a thin layer.

Installation

npm install @emergente-labs/elements-sdk effect
# or
pnpm add @emergente-labs/elements-sdk effect
# or
yarn add @emergente-labs/elements-sdk effect

effect is a peer requirement — the SDK is built on top of it.

Quickstart

import { loadElements } from "@emergente-labs/elements-sdk";

// 1. Mint a PaymentIntent server-side, return its client_secret to the page.
//    The SDK never sees your secret API key.
const elements = await loadElements({
    publishableKey: "pk_test_...",
    clientSecret: "cs_...",
    iframeOrigin: "https://elements.example.com",
});

// 2. Mount the card element into your DOM.
const card = elements.create("payment");
card.mount("#card-container");

// 3. Listen for input state changes (validity, brand, etc.).
card.on("change", (event) => {
    console.log(event.complete, event.brand);
});

// 4. Confirm when the buyer submits.
const result = await elements.confirm({
    element: card,
    billingAddress: {
        firstName: "Ada",
        lastName: "Lovelace",
        lineOne: "1 Analytical Engine Way",
        city: "London",
        postalCode: "SW1A 1AA",
        country: "GB",
    },
    returnUrl: window.location.href,
});

if (result.status === "succeeded") {
    // Payment captured — redirect to confirmation page.
}

3-D Secure (fingerprint + challenge) is handled automatically. The promise only resolves once the intent has reached a terminal status — your code does not need to manage redirects, hidden iframes, or ACS postMessages.

Effect API

import * as Elements from "@emergente-labs/elements-sdk/effect";
import { Effect, Stream } from "effect";

const program = Effect.gen(function* () {
    const elements = yield* Elements.make({
        publishableKey: "pk_test_...",
        clientSecret: "cs_...",
        iframeOrigin: "https://elements.example.com",
    });

    const card = yield* elements.create("payment");
    yield* card.mount("#card-container");

    yield* card.changes.pipe(
        Stream.tap((event) => Effect.log(event)),
        Stream.runDrain,
        Effect.fork,
    );

    return yield* elements.confirm({
        element: card,
        billingAddress: { /* ... */ },
        returnUrl: location.href,
    });
});

Effect.runPromise(program.pipe(Effect.scoped));

When the surrounding Scope closes, every iframe, listener, and fiber is torn down automatically — no manual dispose() call is required.

Configuration

loadElements / Elements.make accept the following options:

| Option | Required | Description | | ---------------- | -------- | --------------------------------------------------------------- | | publishableKey | yes | Your pk_* publishable key. | | clientSecret | yes | Client secret returned when you created the PaymentIntent. | | iframeOrigin | yes | Origin serving the Elements iframe pages. | | appearance | no | Theme + variables + rules forwarded to the iframe. | | apiBase | no | Override the iframe's RPC base URL (defaults to iframeOrigin). |

Element types

| Type | Path | Purpose | | ----------------- | ------------------- | ---------------------------------------- | | payment | /v1/card.html | Card number / expiry / CVC. | | expressCheckout | /v1/express.html | Apple Pay / Google Pay / wallet buttons. | | address | /v1/address.html | Billing or shipping address. |

The iframe pages must be served by your backend at iframeOrigin. This SDK handles the merchant-side glue only — see your provider's docs for hosting the iframe pages themselves.

Errors

Every error raised by the Effect surface is a tagged class re-exported from @emergente-labs/elements-sdk/errors. The Promise API re-throws them verbatim, so instanceof checks work either way:

import { ElementsConfigError, ElementMountError } from "@emergente-labs/elements-sdk/errors";

try {
    await loadElements({ /* ... */ });
} catch (err) {
    if (err instanceof ElementsConfigError) {
        // bad publishable key, missing window, etc.
    }
}

The full set: ElementsConfigError, ElementMountError, ElementNotMountedError, ElementLoadError, UnsupportedActionError, UnexpectedActionError. The ElementsError union is exported for exhaustive Effect.catchTag checks.

Lifecycle

loadElements opens a single root scope. Calling Elements.dispose() closes it, which:

  • unmounts every element created from this instance,
  • detaches the parent-window message listener,
  • interrupts the per-element listener fibers,
  • shuts down the internal PubSub instances.

The Effect API uses the surrounding Scope instead of an explicit dispose() — closing the scope tears everything down.

Browser support

Modern evergreen browsers (Chrome, Firefox, Safari, Edge). The SDK uses postMessage, URLSearchParams, and standard DOM APIs — no polyfills required for supported targets.

Contributing

See CONTRIBUTING.md. Issues and pull requests welcome.

Security

To report a security vulnerability, see SECURITY.md. Please do not open a public issue.

License

MIT — see LICENSE.