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

@alaasync/layersync-web

v0.4.0

Published

LayerSync browser SDK — conversion tracking + server-side CAPI delivery for any JS site.

Readme

@alaasync/layersync-web

Browser SDK for LayerSync — conversion tracking + server-side CAPI delivery for any JavaScript site.

One install, three credentials, zero per-platform integration code. Configuration lives in the LayerSync dashboard; this SDK enqueues events and ships them to LayerSync, which fans them out to Meta CAPI, Google Ads, GA4 Measurement Protocol, TikTok Events API, Pinterest, Snap, LinkedIn, X, and Reddit.

Install

npm install @alaasync/layersync-web
# pnpm add @alaasync/layersync-web
# yarn add @alaasync/layersync-web

Quick start

import { LayerSync } from '@alaasync/layersync-web';

const ls = LayerSync.init({
  siteId:         'YOUR_SITE_ID',
  publishableKey: 'YOUR_API_KEY',
});

// Identify a known user (optional — events still work without this)
ls.identify('user_abc123', {
  email:      '[email protected]',
  phone:      '+15551234567',
  first_name: 'Ada',
  last_name:  'Lovelace',
});

// Track a purchase
ls.track('purchase', {
  order_id: 'O-1024',
  value:    99.95,
  currency: 'USD',
  items: [
    { item_id: 'SKU-A', name: 'Widget', quantity: 2, price: 29.99 },
    { item_id: 'SKU-B', name: 'Gadget', quantity: 1, price: 39.97 },
  ],
});

// Track a page view (auto-fires URL + title + referrer)
ls.page();

// Or with an explicit name
ls.page({ name: 'product_detail' });

That's it. The event is queued locally, POSTed to LayerSync, and fanned out to every connected platform server-side. PII is SHA-256 hashed before transmission.

Canonical events

ls.track('page_view',             { /* auto-filled */ });
ls.track('view_item',             { item_id: 'SKU-A', value: 29.99, currency: 'USD' });
ls.track('view_item_list',        { /* ... */ });
ls.track('view_category',         { /* ... */ });
ls.track('search',                { search_term: 'red widget' });
ls.track('add_to_cart',           { items: [...], value: 29.99, currency: 'USD' });
ls.track('add_to_wishlist',       { /* ... */ });
ls.track('begin_checkout',        { items: [...], value: 99.95, currency: 'USD' });
ls.track('add_payment_info',      { /* ... */ });
ls.track('purchase',              { order_id: '...', value: 99.95, currency: 'USD', items: [...] });
ls.track('refund',                { order_id: '...', value: 99.95, currency: 'USD' });
ls.track('lead',                  { email: '...' });
ls.track('sign_up',               { /* ... */ });
ls.track('complete_registration', { /* ... */ });

Custom event names are also accepted — they pass through to whichever platforms have a mapping for them in your LayerSync dashboard.

Consent

Default: granted. The SDK respects an explicit deny:

ls.setConsent(false);                                     // halt everything
ls.setConsent(true);                                      // resume
ls.setConsent({ meta: 'granted', tiktok: 'denied' });     // per-platform

While granted=false, events are dropped at the SDK and no network requests fire. Set it back to true to resume; nothing is queued during denial.

Pagehide flush

The SDK auto-flushes on pagehide via navigator.sendBeacon so in-flight events aren't lost when the user closes the tab or navigates away. No setup required.

Frameworks

Using React / Next.js? Install @alaasync/layersync-react — it provides <LayerSyncProvider>, useLayerSync(), and auto-pageview tracking for Next.js App Router, Pages Router, and React Router v6.

Auth model

| Field | What | |---|---| | siteId | The numeric site identifier from your LayerSync dashboard. | | publishableKey | The API key associated with that site. Safe to expose in browser bundles — only authorized to POST events for that site. | | apiUrl | Defaults to https://layersynchub.com. Override for self-hosted instances or staging. |

Browser support

ES2019 baseline: Chrome 73+, Firefox 67+, Safari 12.1+, Edge 79+, iOS Safari 12.2+. No IE.

navigator.locks, CompressionStream, sendBeacon, and crypto.subtle are all feature-detected; the SDK works with reduced features when they're missing.

API reference

LayerSync.init(opts)

| Option | Type | Required | Default | |---|---|---|---| | siteId | string \| number | yes | — | | publishableKey | string | yes | — | | apiUrl | string | no | https://layersynchub.com | | consoleLog | boolean | no | false | | consent | boolean \| ConsentMap | no | granted |

Returns a LayerSyncClient. Subsequent calls return the same singleton.

client.identify(externalId, traits?)

ls.identify('user_abc123', {
  email:      '[email protected]',  // SHA-256 before transmission
  phone:      '+15551234567',     // E.164 normalized + SHA-256
  first_name: 'Ada',              // lowercased + SHA-256
  last_name:  'Lovelace',
});

Pass null to clear traits (e.g. on logout).

client.track(name, props?)

Returns void. Errors are absorbed — track() never throws, never blocks. Queued on network failure, retried with exponential backoff. Permanently undeliverable events drop after max_attempts.

client.page(opts?)

Equivalent to track('page_view', { name, url, title }) with auto-detection when the values aren't supplied.

client.setConsent(state)

See above.

client.flush()

Force-drain the queue. Returns a Promise that resolves when the current batch completes. Mostly useful in tests.

License

MIT.