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

@particle-academy/fancy-git-ui

v0.3.1

Published

Controlled React Git surfaces for Fancy UI.

Readme

Fancy Git UI

Controlled, provider-neutral React surfaces for repository state, commit history, and pull/merge requests. Components emit intents; they never invoke Git or a provider API themselves. Every entity has a stable data-git-* handle.

npm install @particle-academy/fancy-git-ui @particle-academy/fancy-git @particle-academy/fancy-file-commons
import "@particle-academy/fancy-git-ui/styles.css";

The styles are a thin default — layout and diff colouring, nothing opinionated. Every rule targets a data-git-* attribute, so restyle by overriding those rather than by forking a component.

Components

| | | |---|---| | <WorkingTree> | Changed paths with staged / unstaged status; emits stage and unstage intents. | | <DiffViewer> | A unified diff, unified or split, with per-hunk accept / reject. | | <CommitHistory> | A log, with a selected commit. | | <RepositoryBrowser> | A tree of the repository at a ref. | | <ReviewList> | Pull / merge requests and their state. | | <BranchPicker> | Branch selection. | | <CommitComposer> | Message + staged paths → a commit intent. | | <CreateReviewForm> | Source, target, title, body → an open-review intent. |

Each is controlled: it takes a value and reports an intent, and does nothing on its own. That is what lets an agent drive the same surface a person is looking at — see the Human+ UX contract in the suite's AGENTS.md.

<DiffViewer>

Takes what fancy-git actually returns:

const diff = await repository.diff({ from: "main", to: "HEAD" });

<DiffViewer value={diff.patch} />

value is a unified diff string, or Diff[] already parsed with parseUnifiedDiff / computeDiff when you want one parse to feed two surfaces. Parsing, hunk ids, word-level segmentation and the merge helpers all come from fancy-file-commons, the same core fancy-diff and fancy-code use — so a diff produced anywhere in the suite renders here.

Accepting hunks

const [acceptance, setAcceptance] = useState<AcceptanceState>({});

<DiffViewer value={diff.patch} acceptance={acceptance} onAcceptanceChange={setAcceptance} />

AcceptanceState is Record<hunkId, "accepted" | "rejected" | "pending">. A hunk with no entry is pending, which is not the same as rejected — without that distinction a review cannot tell whether it is finished. The hunk's control cycles pending → accepted → rejected.

Hunk ids are content-derived and stable, so a decision survives a re-render and a re-parse of the same patch. equal hunks are context and carry no control: there is nothing to accept, and a button implies there is.

Apply the result with mergeResult from fancy-file-commons.

Other props

mode / onModeChange"unified" (default) or "split", which renders before and after side by side, padding the shorter side so a removal stays aligned with what replaced it.

hideContext — drop the equal hunks git wraps around each change.

Handles

Agents and stylesheets both target these; they are a contract, not an implementation detail.

[data-git-working-tree] · [data-git-path] · [data-git-diff] · [data-git-diff-file] · [data-git-hunk] (+ data-hunk-type, data-hunk-status) · [data-git-hunk-toggle] · [data-git-diff-line] · [data-git-diff-side] · [data-git-commit-id] · [data-git-review-number] · [data-git-repository-browser] · [data-git-branch-picker] · [data-git-commit-composer] · [data-git-create-review]

Backends

Pairs with @particle-academy/fancy-git (Node) or particle-academy/fancy-git-php (Composer) — one normalized provider contract across GitHub, GitLab and Bitbucket, so the same surface works against any of them. Mutations support a proposal-first mode: an agent proposes, a person confirms.