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

wakeline

v0.2.0

Published

Wakeline — in-app product guides, checklists, surveys and onboarding for web apps. Re-exports @wakeline/sdk.

Readme

Wakeline

In-app product guides, checklists, surveys and onboarding for web apps. Guides are authored in the Wakeline dashboard; this package renders them.

npm i @wakeline/sdk      # or: npm i wakeline

wakeline and @wakeline/sdk are the same package published under both names — install whichever you prefer.

Prefer no build step? The <script> snippet on your dashboard's install page does the same job and needs no package at all.

Quick start

import { wakeline } from "@wakeline/sdk";

wakeline.init({
  key: "wl_pub_…",                     // publishable key, from Settings → API keys
  apiHost: "https://wakeline.io", // your Wakeline origin
});

// Once your user is known. Extra traits become targeting attributes.
wakeline.identify(user.id, { name: user.name, email: user.email, plan: user.plan });

apiHost is required here. The <script> snippet infers it from its own src; an import has no script tag to read, and guessing would point the SDK at your app's own origin.

Named imports work too, and tree-shake:

import { init, identify, track } from "@wakeline/sdk";

Which entry point?

| | @wakeline/sdk | @wakeline/sdk/loader | |---|---|---| | SDK code | bundled into your app | fetched from your Wakeline origin | | Runtime script fetch | none | one | | Getting SDK updates | you upgrade the package | automatic | | Added weight | ~35 kB gzipped | ~1 kB |

import { wakeline } from "@wakeline/sdk/loader";
wakeline.init({ key: "wl_pub_…", apiHost: "https://wakeline.io" });

The API is identical, so switching is a one-line change.

Use the default where third-party scripts are blocked outright, or when you want the SDK version pinned in your lockfile.

Use /loader to guarantee every visitor runs the current SDK. This matters more than it sounds: if you build a guide using a step type newer than the package version your app shipped with, the bundled entry cannot render it until you upgrade and redeploy. The loader renders it immediately.

Either way your Wakeline origin needs connect-src in your CSP for the API; /loader additionally needs it in script-src.

API

| Call | What it does | |---|---| | init(options) | Start the SDK. Safe to call once; later calls are ignored. | | identify(externalId, traits?) | Attach a user. Traits become targeting attributes. | | track(name, properties?) | Fire a custom event; can trigger guides and complete checklist items. | | page(url?) | Tell the SDK the route changed. Automatic unless autoPage: false. | | show(flowId) | Show a specific guide on demand. | | reset() | Clear the identified user, e.g. on logout. |

Calls made before init() are buffered and replayed, so ordering never matters. Nothing here throws: a fault inside Wakeline must never break your app.

init options

| Option | Type | Default | | |---|---|---|---| | key | string | — | Required. Publishable key (wl_pub_…). | | apiHost | string | — | Required. Your Wakeline origin. | | autoPage | boolean | true | Watch history/pushState for SPA navigation. | | lang | string | — | Force a locale; otherwise the identify trait, then navigator.language. |

Server-side rendering

Safe to import anywhere. Next.js, Nuxt, Remix and SvelteKit all evaluate module scope on the server, so every call no-ops when there is no window rather than throwing, and runs for real on the client.

"use client";
import { useEffect } from "react";
import { wakeline } from "@wakeline/sdk";

export function Wakeline({ user }: { user: { id: string; email: string } }) {
  useEffect(() => {
    wakeline.init({ key: process.env.NEXT_PUBLIC_WAKELINE_KEY!, apiHost: "https://wakeline.io" });
    wakeline.identify(user.id, { email: user.email });
  }, [user.id, user.email]);
  return null;
}

Strict mode double-invokes effects; init is idempotent, so that is fine.

TypeScript

Types ship with the package — no @types needed. WakelineOptions and WakelineClient are exported.

Links

MIT