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

@kookee/sdk

v0.0.29

Published

Official Kookee SDK - Access your blog, changelog, help center, and more

Readme

@kookee/sdk

Official TypeScript SDK for Kookee - the headless CMS for your blog, changelog, and help center.

Features

  • Lightweight - Only ~1.5 KB minified (ESM), no bloat
  • Zero dependencies - Uses native fetch, nothing else
  • TypeScript-first - Full type definitions out of the box
  • Tree-shakeable - Import only what you need
  • Open source - MIT licensed

Installation

npm install @kookee/sdk
# or
pnpm add @kookee/sdk
# or
yarn add @kookee/sdk

Quick Start

import { Kookee } from '@kookee/sdk';

const kookee = new Kookee({
  apiKey: 'your-api-key',
});

// Fetch blog posts
const posts = await kookee.blog.list({ limit: 10 });

// Get a single post by slug
const post = await kookee.blog.getBySlug('hello-world');

Blog

// List posts with pagination
const posts = await kookee.blog.list({ page: 1, limit: 10 });

// Filter by tag slugs
const taggedPosts = await kookee.blog.list({ tags: ['news'] });

// Search posts
const searchResults = await kookee.blog.list({ search: 'tutorial' });

// Get single post by slug
const post = await kookee.blog.getBySlug('my-post');

// Get single post by ID
const postById = await kookee.blog.getById('post-uuid');

// Get all tags with post counts
const tags = await kookee.blog.getTags();

// React to a post
await kookee.blog.react('post-id', { reactionType: 'heart', action: 'add' });

// Get translations
const translations = await kookee.blog.getTranslationsBySlug('my-post');

Help Center

// List categories
const categories = await kookee.help.categories();

// List articles with pagination
const articles = await kookee.help.list({ page: 1, limit: 10 });

// Filter by category slug
const categoryArticles = await kookee.help.list({ category: 'getting-started' });

// Semantic search
const results = await kookee.help.search({ query: 'how to reset password', limit: 5 });

// Get single article
const article = await kookee.help.getBySlug('getting-started');
const articleById = await kookee.help.getById('article-uuid');

// Get article translations
const translations = await kookee.help.getTranslationsBySlug('getting-started');

// AI-powered chat
const response = await kookee.help.chat({
  messages: [{ role: 'user', content: 'How do I reset my password?' }],
});

// Streaming chat
for await (const chunk of kookee.help.chatStream({ messages })) {
  if (chunk.type === 'delta') console.log(chunk.content);
  if (chunk.type === 'sources') console.log('Sources:', chunk.sources);
}

// Vote on article usefulness
await kookee.help.voteUsefulness('article-id', 'yes');

Changelog

// List entries
const entries = await kookee.changelog.list({ page: 1, limit: 10 });

// Filter by type: 'feature' | 'fix' | 'improvement' | 'breaking' | 'security' | 'deprecated' | 'other'
const fixes = await kookee.changelog.list({ type: 'fix' });

// Order by version or date
const sorted = await kookee.changelog.list({ orderBy: 'version', order: 'desc' });

// Get single entry
const entry = await kookee.changelog.getBySlug('v1-0-0');
const entryById = await kookee.changelog.getById('entry-uuid');

// Get translations
const translations = await kookee.changelog.getTranslationsBySlug('v1-0-0');

// React to an entry
await kookee.changelog.react('entry-id', { reactionType: 'fire', action: 'add' });

Announcements

// List announcements
const announcements = await kookee.announcements.list({ page: 1, limit: 10 });

// Filter by type: 'info' | 'warning' | 'critical' | 'promotion' | 'maintenance' | 'newFeature'
const critical = await kookee.announcements.list({ type: 'critical' });

// Exclude already-seen announcements
const unseen = await kookee.announcements.list({ excludeIds: ['id1', 'id2'] });

// Get single announcement
const announcement = await kookee.announcements.getById('announcement-uuid');

// Get translations
const translations = await kookee.announcements.getTranslationsById('announcement-uuid');

Pages

// List pages
const pages = await kookee.pages.list({ page: 1, limit: 10 });

// Search pages
const results = await kookee.pages.list({ search: 'privacy' });

// Get single page
const page = await kookee.pages.getBySlug('privacy-policy');
const pageById = await kookee.pages.getById('page-uuid');

// Get translations
const translations = await kookee.pages.getTranslationsBySlug('privacy-policy');

Feedback

// List feedback posts
const posts = await kookee.feedback.list({ page: 1, limit: 10 });

// Filter by status: 'open' | 'under_review' | 'planned' | 'in_progress' | 'completed' | 'declined'
const planned = await kookee.feedback.list({ status: 'planned' });

// Filter by category: 'feature' | 'improvement' | 'bug' | 'other'
const bugs = await kookee.feedback.list({ category: 'bug' });

// Sort options: 'newest' | 'top' | 'trending'
const trending = await kookee.feedback.list({ sort: 'trending' });

// Get single post with comments
const post = await kookee.feedback.getById('post-uuid');

// Vote on a post
await kookee.feedback.vote('post-id', { action: 'upvote' });

// Get top contributors
const contributors = await kookee.feedback.getTopContributors({ limit: 10 });

Config

// Get a single config value
const config = await kookee.config.getByKey('feature_flags');

// Get multiple config values
const configs = await kookee.config.list({ keys: ['feature_flags', 'theme'] });

Reactions

Blog posts and changelog entries support reactions:

// Available reaction types: 'fire' | 'heart' | 'rocket' | 'eyes' | 'mindblown'
await kookee.blog.react('post-id', { reactionType: 'heart', action: 'add' });

// Remove a reaction
await kookee.blog.react('post-id', { reactionType: 'heart', action: 'remove' });

Localization

Most endpoints support locale options:

// Specify locale
const posts = await kookee.blog.list({ locale: 'de' });

// With fallback to default locale if translation doesn't exist
const post = await kookee.blog.getBySlug('hello-world', { locale: 'de', fallback: true });

Paginated Response

All list endpoints return a paginated response:

interface PaginatedResponse<T> {
  data: T[];
  total: number;
  limit: number;
  offset: number;
  page: number;
  totalPages: number;
}

Error Handling

import { Kookee, KookeeApiError } from '@kookee/sdk';

try {
  const post = await kookee.blog.getBySlug('non-existent');
} catch (error) {
  if (error instanceof KookeeApiError) {
    console.error(`Error ${error.code}: ${error.message}`);
    console.error(`Status: ${error.status}`);
  }
}

Configuration

const kookee = new Kookee({
  apiKey: 'your-api-key',
  baseUrl: 'https://api.kookee.dev', // optional, defaults to production API
});

TypeScript

The SDK is written in TypeScript and provides full type definitions:

import type { BlogPost, BlogPostListItem, BlogTag, PaginatedResponse } from '@kookee/sdk';

License

MIT