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

linkit-react-components

v0.1.17

Published

Authenticated Linkit provider and compact React display primitives.

Readme

Linkit React Components

linkit-react-components provides small, reusable Linkit identity and profile controls for React applications. Every component must be rendered below AuthMiniProvider → LinkitProvider; the package reuses the outer Auth Mini session and never owns login callbacks, token refresh, passwords, cookies, or token audiences.

<AuthMiniProvider authMiniBaseUrl="https://auth.ntnl.io" audiences={["app.example.com", "linkit.ntnl.io"]} autoRedirectToLogin={false}>
  <LinkitProvider linkitBaseUrl="https://linkit.ntnl.io">
    <LinkitAppHeaderUser lang="zh-CN" />
  </LinkitProvider>
</AuthMiniProvider>

API

  • LinkitProvider supplies authenticated Linkit requests, getMe, getProfile, updateProfile, upload, searchUsers, and openDirectConversation.
  • useLinkit reads that provider context.
  • LinkitAvatar renders a fixed-size profile avatar from its public, versioned avatar_url through a native <img src>; the browser reuses that URL through its normal HTTP cache, and a same-size initial fallback appears if the image fails.
  • LinkitUserDisplay renders a profile username; when the profile is unavailable it renders the localized unknown-user label and the complete source user_id.
  • LinkitConversationDisplay renders a group or direct conversation identity.
  • LinkitAppHeaderUser renders an application-header account trigger and Base UI dialog for username, motto, avatar upload, UID copy, passkey registration, sign-in-method settings, and sign out.
  • LinkitUserPicker searches username prefixes and UUID-character user_id prefixes, then writes the chosen user_id in controlled or uncontrolled form usage.
  • LinkitUserInfo is an inline avatar, username, and complete user_id display. Its Base UI popover opens by click, keyboard, or desktop hover and presents the available profile motto plus a real Linkit direct-message action. Pass a prefetched profile for dense tables; otherwise the component fetches the public profile only after its popover opens.

Username and profile semantics

A Linkit username is the sole human-readable user identity. Linkit trims it before persistence, keeps SQLite NOCASE uniqueness semantics, permits Unicode and punctuation, and rejects empty, control-character, and over-80-character values. Consumers must render it as text and URL-encode it when it appears in a path or query.

LinkitProfile contains user_id, username, optional avatar_url, optional motto, optional avatar_attachment_id, and optional updated_at. There is no nickname or display_name field.

Public data and CORS

getProfile(userId) reads the minimal public profile without sending a Bearer token. Public profile data contains user_id, username, the user-authored motto, and optional versioned public avatar_url; search data remains limited to user_id, username, and optional avatar URL. Neither response exposes attachment IDs, email, login methods, sessions, or security data. Authenticated API calls require an outer token whose aud includes linkit.ntnl.io; Bearer CORS never enables credentials. The LinkitUserInfo direct-message action opens a protected Linkit conversation through openDirectConversation(username) and navigates a new Linkit window using only the returned conversation ID—no token is added to the URL.

Styles and dependencies

Import linkit-react-components/styles.css. That stylesheet includes the App Header, UserInfo, and UserPicker form/listbox states. The package uses public Base UI primitives and shadcn-style semantic slots, rather than importing a consumer application's private @/components/ui files. Peer dependencies are React, React DOM, @base-ui/react, lucide-react, and auth-mini-react-components.

Portal layering contract

LinkitUserInfo renders its Base UI popover through PopoverPrimitive.Portal so it can escape local overflow clipping. The consuming application owns the document-level stacking context: apply isolation: isolate to the React mount root that calls createRoot (for the standard Vite mount, #root). Keep the application layer scale coherent—for example, ordinary content < popovers/menus < sticky UI < modal backdrop < dialog < toast.

#root {
  isolation: isolate;
}

The package deliberately does not target #root, body, html, :root, or any host application root. It also deliberately assigns no elevated z-index to .linkit-user-info__popup, so consumer dialogs, sheets, and toast layers remain authoritative.

User picker selection modes

LinkitUserPicker owns the authenticated Linkit lookup UI: it keeps the 180ms debounce, cancels obsolete searches, accepts username and UUID-character prefixes, and returns at most the results enforced by Linkit. Consumers must not recreate that search UI locally.

Single selection is retained as the compatibility surface for existing Linkit, 1Exchange, and OpenAI-LB consumers. It supports controlled value or legacy uncontrolled defaultValue, with onValueChange(userId, user). The owner is Linkit React Components; removal requires consumer migration, a major-version plan, package regression tests, and consumer builds.

<LinkitUserPicker
  name="investor_id"
  value={investorId}
  onValueChange={(userId, user) => setInvestorId(userId)}
/>

Multi selection is controlled-first. Pass multiple, a string[] of selected Linkit user IDs, and onValueChange. The picker deduplicates IDs while preserving selection order; it displays readable username chips, supports individual removal, clear-all, and Backspace removal, and excludes already selected results. With name, it emits one hidden input per selected ID so normal form submission preserves the ordered values.

<LinkitUserPicker
  multiple
  name="member_ids"
  value={memberIds}
  onValueChange={(userIds, users) => setMemberIds(userIds)}
  label="Members"
  lang="en"
/>

The users callback argument contains the selected search records known to the picker. Server APIs must accept and authorize IDs independently: clients cannot treat picker output as permission to add a user, and selected chips intentionally do not expose raw IDs as ordinary visual identity.