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

@jamwidgets/core

v0.1.1

Published

Framework-agnostic API client and types for Jamwidgets

Readme

@jamwidgets/core

Note: This repo is a read-only mirror. Source lives in a private monorepo. For issues/PRs, please open them here and we'll sync changes back.

Framework-agnostic API client, types, and headless controllers for JamWidgets widgets.

Installation

npm install @jamwidgets/core

This is the base package used by @jamwidgets/astro, @jamwidgets/react, and @jamwidgets/solid. Use it directly when building custom integrations or with any JavaScript framework.

API Functions

Comments

import { fetchComments, postComment } from "@jamwidgets/core";

// Fetch comments for a page
const comments = await fetchComments({
  siteKey: "your-key",
  pageId: "my-page",
});

// Post a new comment
await postComment({
  siteKey: "your-key",
  pageId: "my-page",
  authorName: "John",
  content: "Great post!",
  authorEmail: "[email protected]", // optional
  parentId: "comment-id", // optional, for replies
});

Reactions

import { fetchReactions, addReaction, removeReaction } from "@jamwidgets/core";

// Fetch reactions for a page
const { counts, userReactions } = await fetchReactions({
  siteKey: "your-key",
  pageId: "my-page",
});

// Add a reaction
await addReaction({
  siteKey: "your-key",
  pageId: "my-page",
  reactionType: "like", // or 'clap', 'heart', etc.
});

// Remove a reaction
await removeReaction({
  siteKey: "your-key",
  pageId: "my-page",
  reactionType: "like",
});

Forms

import { submitForm } from "@jamwidgets/core";

await submitForm({
  siteKey: "your-key",
  formSlug: "contact",
  data: {
    name: "John",
    email: "[email protected]",
    message: "Hello!",
  },
});

Subscriptions

import { subscribe } from "@jamwidgets/core";

await subscribe({
  siteKey: "your-key",
  email: "[email protected]",
});

Waitlist

import { joinWaitlist } from "@jamwidgets/core";

await joinWaitlist({
  siteKey: "your-key",
  email: "[email protected]",
  name: "John", // optional
  source: "homepage", // optional
});

Feedback

import { submitFeedback } from "@jamwidgets/core";

await submitFeedback({
  siteKey: "your-key",
  type: "bug", // 'bug' | 'feature' | 'general'
  content: "Found an issue...",
  email: "[email protected]", // optional
  pageUrl: "/about", // optional
});

Polls

import { fetchPoll, votePoll } from "@jamwidgets/core";

// Fetch poll data
const poll = await fetchPoll({
  siteKey: "your-key",
  slug: "favorite-framework",
});

// Vote on a poll
await votePoll({
  siteKey: "your-key",
  slug: "favorite-framework",
  selectedOptions: ["option-1", "option-2"],
});

Views

import { getViewCounts, recordView } from "@jamwidgets/core";

// Get view counts
const { views, uniqueVisitors } = await getViewCounts({
  siteKey: "your-key",
  pageId: "my-page",
});

// Record a view
await recordView({
  siteKey: "your-key",
  pageId: "my-page",
});

Announcements

import { fetchAnnouncements, dismissAnnouncement } from "@jamwidgets/core";

// Fetch active announcements
const announcements = await fetchAnnouncements({
  siteKey: "your-key",
});

// Dismiss an announcement
await dismissAnnouncement({
  siteKey: "your-key",
  announcementId: 123,
});

Posts

import { fetchPosts, fetchPost } from "@jamwidgets/core";

// Fetch all published posts
const posts = await fetchPosts({
  siteKey: "your-key",
  tag: "tutorials", // optional filter
  limit: 10, // optional
});

// Fetch a single post
const post = await fetchPost({
  siteKey: "your-key",
  slug: "my-post",
});

Headless Controllers

Controllers manage state without any DOM dependencies. Use them to build custom UI or integrate with any framework.

import {
  SubscribeController,
  FormController,
  ReactionsController,
  CommentsController,
  WaitlistController,
  FeedbackController,
  PollController,
  AnnouncementsController,
  ViewCountsController,
} from "@jamwidgets/core";

// Example: Subscribe controller
const controller = new SubscribeController({ siteKey: "your-key" });

// Subscribe to state changes
controller.subscribe((state) => {
  console.log(state.status); // 'idle' | 'loading' | 'success' | 'error'
  console.log(state.message);
  console.log(state.error);
});

// Submit
await controller.submit("[email protected]");

// Reset
controller.reset();

Available Controllers

| Controller | Purpose | |------------|---------| | SubscribeController | Email subscriptions | | FormController | Form submissions | | ReactionsController | Page reactions | | CommentsController | Threaded comments | | WaitlistController | Waitlist signups | | FeedbackController | Feedback forms | | PollController | Polls and voting | | AnnouncementsController | Site announcements | | ViewCountsController | Page view tracking |

Visitor Management

Reactions and views track visitors using localStorage. For authenticated users, you can set a custom visitor ID:

import { setVisitorId, getVisitorId } from "@jamwidgets/core";

// Set custom visitor ID (e.g., for logged-in users)
setVisitorId("user-123");

// Get current visitor ID
const visitorId = getVisitorId();

// Revert to localStorage-based ID
setVisitorId(null);

Types

All types are exported for TypeScript users:

import type {
  JamWidgetsConfig,
  Comment,
  ReactionCounts,
  JamWidgetsPost,
  Poll,
  Announcement,
  FeedbackType,
  ControllerStatus,
} from "@jamwidgets/core";

License

MIT