Introduction
Multi-trigger inline mentions for React and Vue. Built on a framework-agnostic core.
What is @skyastrall/mentions?
A production-grade mentions input that supports @users, #tags, /commands, and custom triggers — each with its own data source, color, and configuration.
It ships as a core engine and thin framework adapters:
@skyastrall/mentions-core— Framework-agnostic state machine, markup parser, trigger detection. ~9KB gzipped.@skyastrall/mentions-react— React adapter with drop-in component, compound components, and headless hook. ~5KB.@skyastrall/mentions-vue— Vue 3 adapter with composable and compound components. ~5KB.@skyastrall/mentions-svelte— Svelte 5 adapter with composable and compound components. ~9KB.
Three API Layers
Pick the level of control you need:
1. Drop-in Component
One import, one component, works out of the box.
<Mentions
triggers={[{ char: "@", data: users }]}
onChange={(markup, plainText) => {}}
/> <Mentions
:triggers="[{ char: '@', data: users }]"
v-model="markup"
/> <Mentions
triggers={[{ char: "@", data: users }]}
onChange={(markup, plainText) => {}}
/> 2. Compound Components
Control the layout. The library handles state, ARIA, and keyboard navigation.
<Mentions triggers={triggers}>
<Mentions.Editor placeholder="Type @..." />
<Mentions.Portal>
<Mentions.List>
<Mentions.Item render={({ item }) => <UserCard user={item} />} />
</Mentions.List>
</Mentions.Portal>
</Mentions> <Mentions :triggers="triggers">
<MentionsEditor placeholder="Type @..." />
<MentionsPortal>
<MentionsList>
<MentionsItem v-slot="{ item }">
<UserCard :user="item" />
</MentionsItem>
</MentionsList>
</MentionsPortal>
</Mentions> <Mentions {triggers}>
<MentionsEditor placeholder="Type @..." />
<MentionsPortal>
<MentionsList>
<MentionsItem>
{#snippet children({ item })}
<UserCard user={item} />
{/snippet}
</MentionsItem>
</MentionsList>
</MentionsPortal>
</Mentions> 3. Headless Hook / Composable
Full control. You get props, state, and helpers — render whatever you want.
const { inputProps, listProps, getItemProps, editorRef, isOpen, items } =
useMentions({ triggers }); const { aria, editorRef, isOpen, items, handleInput, handleKeyDown } =
useMentions({ triggers }); const api = useMentions({ triggers });
// api.isOpen, api.items, api.aria, api.handleInput, ... Key Features
- Multi-trigger support with per-trigger colors and data sources
- Framework-agnostic core — React, Vue, and Svelte adapters shipped, more coming
- Contenteditable with DOM-first architecture
- Ghost text for AI inline completions (Tab to accept)
- Async data with debounce, abort, and loading states
- Single-line mode with Enter/paste/drop prevention
- WAI-ARIA combobox pattern with keyboard navigation
- ~9KB core + ~5KB adapter gzipped, zero runtime dependencies in core