CASE 02 // 2026

Mentions

@users, #tags, /commands — one tiny core, every framework.

ROLE
Creator
STACK
TypeScript · React · Vue · Svelte
UPDATED
2026-07-10
Mentions library documentation site

Mentions is my open-source, framework-agnostic mention system: @users, #tags, and /commands from one ~14KB core with zero dependencies, working across React, Vue, and Svelte, with AI ghost-text completions built in.

“One ~14KB headless core drives mentions in React, Vue, and Svelte. Every alternative I benchmarked was heavier and locked to one framework.”

— Gagan Raj

CONSTRAINTS

  • Core budget: stay small enough that nobody thinks twice about adding it
  • Zero runtime dependencies, so no supply-chain surface
  • One behaviour spec across three frameworks
  • WAI-ARIA compliant out of the box

THE BUILD

While building Dataweaver I needed mentions in a chat input: @columns, /commands, the pattern every product eventually grows. Every library I evaluated was welded to one framework, heavy, and unaware that inputs now autocomplete with AI. I wrote my own core and figured other developers were stuck in the same spot.

The design bet was headless-first: a plain TypeScript engine that owns parsing, matching, and selection state, with thin adapters per framework. React, Vue, and Svelte each get an idiomatic wrapper around the same core, so behaviour stays identical and fixes land once. Ghost-text AI completion is a first-class provider interface rather than a bolt-on, because that is how people type now.

DECISIONS — INCLUDING THE REJECTED ONES

Architecture

CHOSE Headless TypeScript core with per-framework adapters

REJECTED A React component ported twice

Ports drift. A single engine with thin adapters keeps three frameworks pixel-identical in behaviour and cuts the maintenance to one surface.

Dependencies

CHOSE Zero

REJECTED Pulling in a positioning or parsing library

A utility library that brings friends stops being a utility. The whole thing fits in ~14KB and audits in one sitting.

AI completions

CHOSE Ghost-text provider interface in the core

REJECTED Leaving AI integration to userland

Suggest-as-you-type is the modern default. Making it a provider keeps the core dependency-free while letting apps plug in any model.

OUTCOME

  • ~14KB core, zero dependencies
  • Ships for React, Vue, and Svelte from one engine
  • WAI-ARIA compliant listbox and combobox semantics
  • Extracted from a production need inside Dataweaver

CRAFT LEDGER

  • Headless core + adapters
  • Ghost-text provider API
  • Zero-dependency build
  • Framework parity tests