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

inline-reference

v0.2.1

Published

**inline-reference** is a small React component library for building **inline mentions, slash commands, and tag references** – similar to what you see in editors like Notion, Linear, or Cursor.

Readme

inline-reference

inline-reference is a small React component library for building inline mentions, slash commands, and tag references – similar to what you see in editors like Notion, Linear, or Cursor.

It lets you:

  • Type a trigger (like @, /, or #)
  • Show a dropdown positioned at the cursor
  • Insert a “pill” reference into a rich text input
  • Read structured segments (plain text vs references) from the editor

Designed to work nicely with shadcn/ui and Tailwind CSS, but usable in any React app.


Installation

npm install inline-reference @floating-ui/react
# or
pnpm add inline-reference @floating-ui/react

Peer dependencies (expected to be installed in your app):

  • react >= 18
  • react-dom >= 18
  • @floating-ui/react >= 0.27

Scaffold a shadcn-style local file

If you prefer true shadcn-style source code in your own project instead of importing directly from the package, you can scaffold a local file:

npm install inline-reference @floating-ui/react
npx inline-reference add

This will create:

  • components/ui/inline-reference.tsx (if components/ui exists or is created), or
  • src/components/ui/inline-reference.tsx (if your project uses src/components/ui)

After that you can import from your own components/ui directory:

import {
  InlineReference,
  InlineReferenceInput,
  InlineReferenceContent,
  InlineReferenceList,
  InlineReferenceItem,
  InlineReferenceEmpty,
  InlineReferenceGroup,
  InlineReferenceSeparator,
} from "@/components/ui/inline-reference"

If the file already exists and you want to overwrite it with the latest version from the package, run:

npx inline-reference add --force

Quick start

Basic “mention someone with @” example:

import * as React from "react"
import {
  InlineReference,
  InlineReferenceInput,
  InlineReferenceContent,
  InlineReferenceList,
  InlineReferenceItem,
  InlineReferenceEmpty,
  type InlineReferenceItemData,
} from "inline-reference"

const people: InlineReferenceItemData[] = [
  { id: "1", label: "John Doe", role: "Engineer" },
  { id: "2", label: "Jane Smith", role: "Designer" },
]

export function CommentEditor() {
  return (
    <InlineReference>
      <InlineReferenceInput placeholder="Type @ to mention someone..." />

      <InlineReferenceContent trigger="@" items={people}>
        <InlineReferenceEmpty>No people found.</InlineReferenceEmpty>

        <InlineReferenceList>
          {(item) => (
            <InlineReferenceItem key={item.id} value={item}>
              <div className="flex items-center gap-2">
                <div className="flex size-6 items-center justify-center rounded-full bg-primary/10 text-xs font-medium">
                  {item.label.charAt(0)}
                </div>
                <div>
                  <div className="text-sm font-medium">{item.label}</div>
                  {item.role && (
                    <div className="text-xs text-muted-foreground">
                      {String(item.role)}
                    </div>
                  )}
                </div>
              </div>
            </InlineReferenceItem>
          )}
        </InlineReferenceList>
      </InlineReferenceContent>
    </InlineReference>
  )
}

Multiple triggers (@, /, #, …)

You can render multiple InlineReferenceContent blocks under a single InlineReference and use different triggers for different data sets:

const people = [
  { id: "1", label: "John Doe" },
  { id: "2", label: "Jane Smith" },
]

const commands = [
  { id: "file", label: "file", description: "Attach a file" },
  { id: "code", label: "code", description: "Insert a code block" },
]

const tags = [
  { id: "bug", label: "bug" },
  { id: "feature", label: "feature" },
]

export function MultiTriggerEditor() {
  return (
    <InlineReference>
      <InlineReferenceInput placeholder="Type @, /, or #..." />

      <InlineReferenceContent trigger="@" items={people}>
        <InlineReferenceEmpty>No people found.</InlineReferenceEmpty>
        <InlineReferenceList>
          {(item) => (
            <InlineReferenceItem key={item.id} value={item}>
              @{item.label}
            </InlineReferenceItem>
          )}
        </InlineReferenceList>
      </InlineReferenceContent>

      <InlineReferenceContent trigger="/" items={commands}>
        <InlineReferenceEmpty>No commands found.</InlineReferenceEmpty>
        <InlineReferenceList>
          {(item) => (
            <InlineReferenceItem key={item.id} value={item}>
              <span className="text-sm">/{item.label}</span>
              <span className="ml-auto text-xs text-muted-foreground">
                {String(item.description)}
              </span>
            </InlineReferenceItem>
          )}
        </InlineReferenceList>
      </InlineReferenceContent>

      <InlineReferenceContent trigger="#" items={tags}>
        <InlineReferenceEmpty>No tags found.</InlineReferenceEmpty>
        <InlineReferenceList>
          {(item) => (
            <InlineReferenceItem key={item.id} value={item}>
              #{item.label}
            </InlineReferenceItem>
          )}
        </InlineReferenceList>
      </InlineReferenceContent>
    </InlineReference>
  )
}

Controlled mode (reading structured content)

If you want to save the editor contents as structured data (text segments and reference segments), use the controlled API:

import { type Segment } from "inline-reference"

export function ControlledEditor() {
  const [segments, setSegments] = React.useState<Segment[]>([])

  return (
    <div className="space-y-3">
      <InlineReference value={segments} onValueChange={setSegments}>
        <InlineReferenceInput placeholder="Type @ to mention someone..." />
        {/* ...InlineReferenceContent blocks... */}
      </InlineReference>

      <pre className="text-xs bg-muted rounded-md p-3 max-h-64 overflow-auto">
        {JSON.stringify(segments, null, 2)}
      </pre>
    </div>
  )
}

Segment is a union of:

  • Text segments{ type: "text"; value: string }
  • Reference segments{ type: "reference"; trigger; value; label; data? }

so you can store and replay the editor content however you like.


Styling and design tokens

This library ships with Tailwind / shadcn-style classes baked into the components:

  • Uses tokens like bg-popover, bg-accent, text-muted-foreground, border-input, etc.
  • Expects you to have a Tailwind + CSS variable setup similar to a standard shadcn/ui app.

To customize styles:

  • Pass className to InlineReferenceInput, InlineReferenceContent, InlineReferenceItem, etc.
  • Override the .inline-reference-pill class in your CSS to change how pills look.

Example (global CSS):

.inline-reference-pill {
  border-radius: 9999px;
  background: color-mix(in srgb, var(--accent) 70%, transparent);
}

API surface

Components

  • InlineReference – root provider, wraps the editor and dropdowns.
  • InlineReferenceInput – the contentEditable input.
  • InlineReferenceContent – positions and renders a dropdown for a specific trigger.
  • InlineReferenceList – renders a scrollable list of items.
  • InlineReferenceItem – a selectable item row.
  • InlineReferenceEmpty – rendered when there are no matching items.
  • InlineReferenceGroup – optional grouping/heading within a dropdown.
  • InlineReferenceSeparator – simple separator line within the dropdown.

Types

  • Segment
  • TextSegment
  • ReferenceSegment
  • InlineReferenceItemData

Development / demo app

This repo also includes a small Next.js demo app that showcases:

  • Basic mentions with @
  • Slash commands with /
  • Tags with #
  • File references
  • Controlled mode with live segments JSON

To run the demo locally:

npm install
npm run dev

Then open http://localhost:3000 in your browser.