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

wanikani-v2-client

v0.3.0

Published

A typed, ergonomic client for the WaniKani API v2

Downloads

26

Readme

wanikani-v2-client

A typed, zero-dependency, ergonomic TypeScript client for the WaniKani API v2.

Works in the browser, Node.js 20+, and Bun.

Installation

npm install wanikani-v2-client

Quick Start

import { createWaniKaniClient } from "wanikani-v2-client";

const client = createWaniKaniClient({
  apiToken: "your-api-token",
});

// Get current user
const user = await client.getUser();
console.log(user.data.username, "level", user.data.level);

// Iterate all subjects (auto-paginates)
for await (const subject of client.listSubjects({ levels: [1, 2] })) {
  console.log(subject.data.characters);
}

// Create a review
await client.createReview({
  subject_id: 123,
  incorrect_meaning_answers: 0,
  incorrect_reading_answers: 1,
});

Configuration

const client = createWaniKaniClient({
  apiToken: "your-token", // Required
  baseUrl: "https://...", // Default: https://api.wanikani.com/v2
  revision: "20170710", // Default: 20170710
  maxRetries: 3, // Default: 3 (retries on 429/500/503)
  fetch: customFetch, // Optional custom fetch implementation
});

Endpoints

| Resource | Methods | | ------------------------- | -------------------------------------------------------------------------------------- | | Assignments | getAssignment, listAssignments, startAssignment | | Level Progressions | getLevelProgression, listLevelProgressions | | Resets | getReset, listResets | | Reviews | getReview, listReviews, createReview | | Review Statistics | getReviewStatistic, listReviewStatistics | | Spaced Repetition Systems | getSpacedRepetitionSystem, listSpacedRepetitionSystems | | Study Materials | getStudyMaterial, listStudyMaterials, createStudyMaterial, updateStudyMaterial | | Subjects | getSubject, listSubjects | | Summary | getSummary | | User | getUser, updateUser | | Voice Actors | getVoiceActor, listVoiceActors |

All list* methods return an AsyncIterable that automatically paginates through all results.

Error Handling

import { WaniKaniApiError, WaniKaniRateLimitError } from "wanikani-v2-client";

try {
  await client.getAssignment(999999);
} catch (error) {
  if (error instanceof WaniKaniRateLimitError) {
    console.log("Rate limited, resets at:", error.resetAt);
  } else if (error instanceof WaniKaniApiError) {
    console.log("API error:", error.status, error.apiMessage);
  }
}

Transient errors (429, 500, 503) are automatically retried with exponential backoff.

Documentation

See docs/usage.md for the full usage guide.

Contributing

npm install
npm run build

Scripts

| Command | Description | | -------------------- | ---------------------------------- | | npm run build | Build the library | | npm run test | Run unit tests | | npm run test:e2e | Run E2E tests against the real API | | npm run type-check | Type-check without emitting | | npm run lint | Lint with oxlint | | npm run fmt | Format with oxfmt | | npm run fmt:check | Check formatting |

E2E Tests

E2E tests validate response shapes against the real WaniKani API. They are skipped automatically when no API key is set.

WANIKANI_API_KEY=your-token npm run test:e2e

Releasing

To publish a new version to npm:

npm version patch   # or minor, or major
git push --follow-tags

The v* tag push triggers a GitHub Actions workflow that runs the full check suite (lint, format, types, tests, build) and publishes to npm with provenance. A GitHub Release with auto-generated notes is created alongside it.

Requires an NPM_TOKEN secret in the repo settings (Settings > Secrets and variables > Actions).

Project Structure

src/
  client.ts          # createWaniKaniClient entry point
  index.ts           # Public exports
  types/             # TypeScript type definitions for API resources
  endpoints/         # Endpoint method factories
  utils/             # Shared utilities (errors, params, retry)
tests/
  client.test.ts     # Unit tests for client behavior
  utils/             # Unit tests for utilities
  e2e/               # E2E tests against the real API
docs/
  usage.md           # Full usage guide

License

MIT