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

huckleberry-js

v0.2.0

Published

Unofficial read-only TypeScript client for the Huckleberry baby-tracking app (Firebase). Runs on Cloudflare Workers, Node 18+, and browsers. Not affiliated with Huckleberry Labs.

Readme

huckleberry-js

Unofficial, read-only TypeScript client for the Huckleberry baby-tracking app's Firebase backend. A fetch-based client that runs anywhere modern JS does — Cloudflare Workers, Node 18+, and browsers — with zero runtime dependencies and first-class types.

npm CI license

⚠️ Disclaimer

This is an unofficial, independent project. It is not affiliated with, endorsed by, sponsored by, or in any way officially connected to Huckleberry Labs, Inc. or any of its subsidiaries or affiliates. "Huckleberry" and related names, marks, and logos are trademarks of their respective owners and are used here for identification purposes only.

This library interacts with undocumented, private endpoints that may change or break at any time. It is provided "as is", without warranty of any kind, and you use it entirely at your own risk. The authors accept no liability for account issues, data loss, or any damages arising from its use. Only use it with credentials you own, and in accordance with Huckleberry's Terms of Service.

Why this exists

The Huckleberry mobile app stores data in Firebase. Official Firebase SDKs talk to Firestore over gRPC, which can't run on Cloudflare Workers. Firestore's REST API accepts the same Firebase ID token and enforces the same security rules, so this library reads your data over plain HTTPS fetch — making it portable to Workers, edge runtimes, Node, and the browser.

Install

npm install huckleberry-js
import { HuckleberryClient } from "huckleberry-js";

Until the first npm release is published you can consume it directly from GitHub — npm install RobErskine/huckleberry-js — or as a local file: dependency.

Getting started

1. Credentials

Authenticate with the same email + password you use to sign in to the Huckleberry app. Store them as secrets (env vars / a secrets manager / Workers secrets) — never commit them.

export HUCKLEBERRY_EMAIL="[email protected]"
export HUCKLEBERRY_PASSWORD="your-password"

2. Authenticate and read a summary

import { HuckleberryClient } from "huckleberry-js";

const client = new HuckleberryClient();
await client.authenticate(process.env.HUCKLEBERRY_EMAIL!, process.env.HUCKLEBERRY_PASSWORD!);

const user = await client.getUser();
const cid = user!.childList[0].cid; // first child's id

// One-call heads-up rollup: last fed / nap / diaper / pump + any active timers
const summary = await client.getDashboardSummary(cid);
console.log(summary);

3. Pull history for a range

const since = new Date(Date.now() - 24 * 3600 * 1000);
const sleeps = await client.listSleepIntervals(cid, since, new Date());

start / end accept a Date or epoch seconds.

Namespaced API (optional, ergonomic)

The same reads grouped by resource — handy when you'd rather not memorize the flat method names. These delegate to the methods above (both styles are fully supported), and list methods take a { start, end } range:

const kids = await client.user.listChildren();
const cid = kids[0].cid;

const range = { start: new Date("2026-06-01"), end: new Date() };
await client.sleep.list(cid, range);
await client.feed.list(cid, range);     // breast, bottle, or solids
await client.diapers.list(cid, range);
await client.activities.list(cid, range);
await client.pump.list(cid, range);
await client.health.list(cid, range);
await client.health.getLatestGrowth(cid);

const summary = await client.dashboard.summary(cid);

Errors

Every error extends HuckleberryError and carries machine-readable fields — category (auth | not_found | invalid_input | api | network), retryable, and a human/LLM-actionable recovery hint (err.toJSON() returns that envelope). AuthError and FirestoreError keep their existing status/body shape, so prior instanceof checks still work.

Reusing a session (serverless / edge)

Authenticate once, persist the returned Session (the refreshToken + uid is enough), and rehydrate later. The client auto-refreshes the ID token and invokes onSession whenever it rotates, so you can re-persist it:

const client = new HuckleberryClient({
  session: stored, // { idToken, refreshToken, uid, expiresAt }
  onSession: async (s) => kv.put("session", JSON.stringify(s)),
});

const summary = await client.getDashboardSummary(cid); // refreshes if needed

Set expiresAt: 0 on a rehydrated session to force an immediate refresh (useful when you only persisted the refresh token).

Cloudflare Workers

export default {
  async fetch(req: Request, env: Env): Promise<Response> {
    const stored = await env.KV.get("session", "json");
    const client = new HuckleberryClient({
      session: stored ?? undefined,
      onSession: (s) => env.KV.put("session", JSON.stringify(s)),
    });
    if (!stored) await client.authenticate(env.HUCKLEBERRY_EMAIL, env.HUCKLEBERRY_PASSWORD);

    const summary = await client.getDashboardSummary(env.CHILD_ID);
    return Response.json(summary);
  },
};

API (v1, read-only)

| Method | Returns | | --- | --- | | authenticate(email, password) | Session | | ensureSession() | refreshes the token if near expiry | | getSession() | current Session or null | | getUser() / getChild(cid) | account / child profile | | getSleep/getFeed/getDiaper/getPump/getHealth(cid) | tracker parent doc (active timer + prefs.last*) | | listSleepIntervals/listFeedIntervals/listDiaperIntervals/listPumpIntervals/listActivityIntervals(cid, start, end) | history rows (handles multi batches) | | getDashboardSummary(cid, name?) | DashboardSummary rollup |

Lower-level Firestore REST helpers (FirestoreRest, decodeValue, buildStartRangeQuery, …) and all Firebase types are also exported from the package root if you need to go beyond the high-level client.

MCP server

Expose your Huckleberry data to Claude (and any MCP client) as read-only tools. Two transports ship with the package:

  • Local (stdio)npx -p huckleberry-js huckleberry-mcp, runs on Node (no Bun required). Best for Claude Desktop on your own machine.
  • Remote (Cloudflare Workers) — deploy huckleberry-js/mcp/worker to the edge for an always-on, shareable endpoint. (A form Bun-only clients can't run.)

The MCP SDK is an optional peer dependency — the core library stays zero-dependency; install @modelcontextprotocol/sdk only to run the stdio server. See docs/mcp.md for setup, config, and the trade-offs between the two forms.

Smoke test

The single most important check — proves auth and a real Firestore REST read work against your account:

npm run build
[email protected] HUCKLEBERRY_PASSWORD=secret npm run smoke

It prints your child list and a dashboard summary.

Develop

npm install
npm run build       # emits dist/
npm run typecheck
npm test            # vitest: value decoder, query builder, multi-container expansion, auth/refresh, rollup

See CONTRIBUTING.md for the full workflow and release steps.

Docs

License

MIT © RobErskine. Not affiliated with Huckleberry Labs, Inc.