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

@adpharm/bit

v0.1.19

Published

A lightweight CLI for pulling shared files from a bit-compatible host directly into your project — and pushing local files back up. Tracks what you've synced so drift checks, re-pushes, and renames don't need you to re-type slugs.

Readme

@adpharm/bit

A lightweight CLI for pulling shared files from a bit-compatible host directly into your project — and pushing local files back up. Tracks what you've synced so drift checks, re-pushes, and renames don't need you to re-type slugs.

Installation

npm install -g @adpharm/bit
# or, one-off:
bunx @adpharm/bit@latest <command>

Quick start

bit init                                         # one-time per repo
bit login                                        # browser-based auth
bit pull my-project/src --to ./src               # pulls + auto-tracks
bit push ./src/utils/foo.ts                      # tracked → slug resolved from manifest
bit status                                       # drift-check everything tracked
bit ls my-project --verbose                      # who pushed what, when
bit log my-project/foo                           # recent push history for a file

After bit init, --host is optional on every subsequent command — it's read from bit.config.json.

Configuration

bit.config.json

Written by bit init at the repo root. Extended by tracked-path commands as you use them.

{
  "host": "https://bit.adpharm.digital",
  "tracked": [
    { "path": ".claude/skills/my-skill", "slug": "skills/my-skill", "kind": "folder" },
    { "path": "src/components/Button.tsx", "slug": "my-project/ui/button", "kind": "file" }
  ]
}

Never edit tracked by hand — use bit track, bit untrack, bit mv, bit retarget, or let bit push / pull / import auto-manage it. Entries are sorted on every write to keep git diffs clean.

.bit/state.json

Written under a .bit/ directory next to bit.config.json. The whole .bit/ directory is gitignored automatically by bit init. Records the version_number and content hash the CLI last successfully synced for each remote slug. This is what makes bit status distinguish "you edited locally" from "the server moved" — and what powers bit push's --force-with-lease precondition (server refuses if a teammate pushed since you last synced).

Note: this is not a lockfile in the package-lock.json / bun.lock sense — those are committed reproducibility manifests. This is machine-local sync state, more like .git/index. Hidden directory mirrors the .git/ / .vscode/ / .claude/ convention.

{
  "entries": {
    "my-project/ui-button": { "version": 7, "hash": "<sha256>", "syncedAt": "2026-04-29T..." }
  }
}

Don't commit it, don't share it. Delete the .bit/ directory any time to reset baselines (next push or pull will re-establish them; bit status falls back to a two-way diff in the meantime).

Host resolution

| Source | Where | When to use | |---|---|---| | --host <url> flag | CLI arg | Per-invocation override | | BIT_HOST env var | Shell env | CI, one-off scripts | | bit.config.jsonhost | Repo root (walks up) | Normal per-project config | | Built-in default | Hardcoded | https://bit.adpharm.digital if nothing else is set |

Auth

| Source | Where | |---|---| | BIT_TOKEN env var | Shell env — overrides the file | | ~/.bit/credentials | Written by bit login, keyed by host, 0600 perms |

Tokens expire after 90 days of inactivity (sliding — every successful call resets the clock) or 1 year absolute, whichever comes first. When a token dies, requests return 401 and bit login re-auths.


Commands

bit init

Set up the current repo for use with bit.

bit init

Prompts for host URL, whether to install the bundled Claude Code skill, and whether to run bit login. Safe to re-run.

| | Description | |---|---| | --host <url> | Skip the host prompt | | --yes | Accept all defaults, no prompts | | --skill-only | Skip config + login; just (re)install the skill |


bit login / bit logout

Browser-based device auth (like Vercel or GitHub CLI). Token stored in ~/.bit/credentials.

bit logout revokes the token server-side before clearing the local file, so the token is dead everywhere. If the server is unreachable it warns and still clears the local copy — the token will then expire via the idle window. A BIT_TOKEN set in the environment is left untouched (CI tokens aren't killed by an interactive logout).

bit login
bit logout

| | Description | |---|---| | --host <url> | Override the host from bit.config.json |


bit skill install

Copy the bundled Claude Code agent skill into .claude/skills/bit-cli/SKILL.md. Use after upgrading @adpharm/bit.

bit skill install           # prompts before overwriting
bit skill install --force   # overwrite silently

bit push

Push a file or folder to a project. Auto-adds a manifest entry on success.

bit push <localPath> [slug]

Requires a token (run bit login first). The target project must already exist.

| | Description | |---|---| | <localPath> | Local file or folder to upload | | [slug] | Remote slug; omit to use the tracked slug for <localPath> | | --host <url> | Override the host | | --no-track | Don't add or update a manifest entry (one-off push). Also skips the .bit/state.json baseline write. | | --force | Skip the --force-with-lease precondition — overwrite even if the remote moved since your last sync. |

Behaviour

  • Auto-tracks the path on success unless --no-track is passed.
  • Slug optional when trackedbit push ./foo.ts re-pushes using the stored slug.
  • Slug mismatch — if <localPath> is already tracked with a different slug and you pass a new one, you'll be prompted to confirm the retarget (skipped with --no-track).
  • --force-with-lease precondition (default): if .bit/state.json has a baseline for a slug, that version_number is sent as expectedVersion. The server refuses the whole batch with 409 if any slug has moved since — you'll see (you: vN, server: vM) per stale slug. Run bit pull to update, or pass --force to overwrite. Slugs without a baseline (fresh pushes) skip the check.
  • Existing remote files are overwritten (upsert by slug) once the precondition passes.
  • Versioned: each push creates a restorable snapshot, visible in the file's history view in the web UI (tagged cli). Squashes with other saves from the same user inside a 60s window. The new version_number is recorded into .bit/state.json so the next push knows its baseline.
  • Ignored locally: node_modules, .git, dist, build, .next, .turbo, .cache, .DS_Store.
  • Cap: 500 files per push.

Examples

bit push ./Button.tsx my-project/ui/button       # first push → tracks
bit push ./Button.tsx                            # subsequent → slug from manifest
bit push ./Button.tsx my-project/other/slug      # prompts to retarget
bit push ./snapshot.tsx project/snapshot --no-track
bit push ./src my-project/src                    # folder

bit pull

Pull every file under a folder (or an entire project). Preserves structure under --to. Auto-adds a folder-kind manifest entry.

bit pull <slug> --to <dir>

| | Description | |---|---| | <slug> | <project> or <project>/<folder> | | --to <dir> | Local directory (created if missing) | | --host <url> | Override the host | | --force | Overwrite existing files without prompting |

bit pull skills/landing-page-spec --to ./.claude/skills/landing-page-spec

bit import

Pull a single file. Auto-adds a file-kind manifest entry.

bit import <slug> --to <path>

| | Description | |---|---| | <slug> | The file's slug | | --to <path> | Output directory or explicit file path (has an extension) | | --host <url> | Override the host |

--to behaviour

| Value | Result | |---|---| | ./src/components (directory) | Writes to ./src/components/<folders-from-slug>/<filename> | | ./src/components/MyButton.tsx (has extension) | Writes directly to that exact path, ignoring slug folders |


bit status

Check whether tracked paths match the registry. Exits 1 when anything is out of sync.

bit status              # walk the whole manifest (CI-friendly)
bit status <path>       # check one tracked file or folder

| | Description | |---|---| | [path] | A tracked file or folder; omit to check everything | | --host <url> | Override the host | | --check | Silent mode — exit 0 (in sync) or 1 (drift), no output |

Output

When .bit/state.json has a baseline for a slug, status reports a three-way state with a (vN → vM) arrow:

| State | Marker | Meaning | Safe action | |---|---|---|---| | local-ahead | | You edited locally; remote unchanged. | bit push | | remote-ahead | | Remote moved; your local is unchanged. | bit pull | | diverged | | Both sides moved. | Manual reconcile or bit pull --force / bit push --force | | in-sync | | Local matches current remote. | — |

Without a baseline (fresh clone, never pushed/pulled), it falls back to a two-way content-diff with a unified patch — same as before. Run bit pull or bit push once to establish baselines.

Other outcomes:

  • missing locally — tracked path not on disk.
  • remote slug gone — tracked slug 404s.
  • local-only — file present locally but not on remote (folder entries only).

Hash-based hints: when a tracked path is missing locally but another file in the repo has matching content, status suggests bit mv. When a slug 404s but a different slug in the same project has matching content, status suggests bit retarget. Suggestions are never applied automatically.

bit status
bit status ./src/components/Button.tsx
bit status ./src/components/Button.tsx --check

bit ls

List remote slugs under a project or prefix. No download, no side effects — useful for confirming a slug exists before pulling.

bit ls <prefix>
bit ls <prefix> --verbose

| | Description | |---|---| | <prefix> | Project slug or projectSlug/sub/path | | --host <url> | Override the host | | --verbose | Show version, last-modified time, and last pusher's display name. Requires login — pusher names aren't returned to unauthenticated callers. |

bit ls my-project
bit ls my-project/components
bit ls my-project --verbose
# my-project/components/button-tsx  v5  2 hours ago    Ben Honda
# my-project/components/card-tsx    v2  yesterday      Alice Reyes

bit log

Show recent push history for a single file. Auth-required — version history exposes pusher names. Output is newest-first.

bit log <slug>
bit log <slug> --limit 50

| | Description | |---|---| | <slug> | Full file slug (e.g. my-project/skills/skill-auditor) | | --host <url> | Override the host | | --limit <n> | Number of versions to show (default 20, max 100) |

bit log my-project/components/button-tsx
# v5  2 hours ago     Ben Honda     bit push
# v4  yesterday       Alice Reyes
# v3  3 days ago      Ben Honda     (restore) Restored from version 1

Same-author pushes within 60 seconds squash into one version_number. The history is therefore at-checkpoint granularity, not at-keystroke. Surfaced in bit log's footer too.


bit track / bit untrack

Retrofit or remove a manifest entry without pushing or pulling.

bit track <path> <slug>       # default kind inferred from the filesystem
bit track <path> <slug> --kind folder
bit untrack <path>            # removes entry only; does not delete files

bit mv

Update the manifest after a local rename. Does not touch disk — run git mv (or rename the file) first.

bit mv <old> <new>

bit retarget

Change the remote slug a tracked path points at. Use when a slug was renamed on the server.

bit retarget <path> <new-slug>

API

The CLI expects the host to expose:

GET  /api/bit/:projectSlug/*                           → single file
GET  /api/bits/:projectSlug?prefix=…                   → list every file under a folder prefix
GET  /api/bits/:projectSlug?verbose=1                  → list with version + last_pusher (requires Bearer token)
POST /api/bits/:projectSlug                            → push (upsert) a batch of files (requires Bearer token)
GET  /api/log/:projectSlug/*?limit=N                   → version history for a single file (requires Bearer token)
POST /api/cli/auth/start                               → begin device-auth flow
POST /api/cli/auth/poll                                → poll for approval, receive token once on success
GET  /api/cli/auth/whoami                              → identify the current Bearer token
POST /api/cli/auth/logout                              → revoke the Bearer token used to call it

Single-file response

{
  "name": "Button.tsx",
  "slug": "my-project/ui-button",
  "content": "...",
  "updated_at": "2026-04-29T12:34:56Z",
  "version_number": 5
}

version_number is the latest file_versions row's number. null if the file has no version history yet.

List response

{
  "projectSlug": "my-project",
  "prefix": "components",
  "files": [
    {
      "name": "Button.tsx",
      "slug": "my-project/components/button-tsx",
      "content": "...",
      "updated_at": "2026-04-29T12:34:56Z",
      "version_number": 5
    }
  ]
}

When called with ?verbose=1 and a valid Bearer token, each file additionally carries last_pusher: { display_name } | null.

Push request

POST /api/bits/:projectSlug
Authorization: Bearer <token>
Content-Type: application/json

{
  "files": [
    { "path": "src/utils/foo.ts", "content": "…", "expectedVersion": 3 }
  ]
}

expectedVersion is optional — when present, the server pre-checks every guarded slug against its current version_number in a single query and refuses the whole batch with 409 if any have moved. This is --force-with-lease semantics.

Success:

{ "written": 1, "files": [ { "slug": "my-project/src/utils/foo-ts", "version_number": 4 } ] }

Conflict (409):

{
  "error": "Push refused — slugs moved since baseline",
  "conflicts": [
    { "slug": "my-project/components/button-tsx", "yourBaseline": 3, "currentVersion": 5 }
  ]
}

currentVersion: null means the file no longer exists (or never did) on the server.

File-log response

{
  "slug": "my-project/components/button-tsx",
  "versions": [
    {
      "version_number": 5,
      "created_at": "2026-04-29T12:34:56Z",
      "kind": "edit",
      "message": "bit push",
      "user": { "display_name": "Ben Honda" }
    }
  ]
}

Newest first. kind is "edit" (normal save) or "restore" (produced by a UI restore action). user is null for entries with no recorded author.

Status codes

401 missing/invalid token · 404 project or file not found · 409 expectedVersion mismatch (push) · 413 payload too large (>500 files) · 429 rate-limited.