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

@abraca/nuxt

v1.6.0

Published

First-class Nuxt module for the Abracadabra CRDT collaboration platform

Readme

@abraca/nuxt

npm version npm downloads License Nuxt

First-class Nuxt 4 module for the Abracadabra CRDT collaboration platform. Drop real-time collaborative documents, multi-user awareness, offline-first sync, and a full rich-text editor into any Nuxt app.

Features

  • Real-time collaborative editing via WebSocket + Yjs CRDT
  • Offline-first with IndexedDB persistence and background sync queue
  • Multi-user awareness — cursors, presence, typing indicators, voice/video
  • TipTap rich-text editor with 30+ built-in extensions
  • Built-in page renderers: Kanban, Table, Calendar, Gallery, Outline
  • Full-text search with trigram indexing
  • File uploads with offline blob caching
  • Passkey (WebAuthn) authentication
  • Server-side rendering with Nitro plugin system and doc cache
  • Extensible plugin architecture

Requirements

  • Nuxt >= 4
  • @abraca/dabra >= 1.0.0
  • @tiptap/core, @tiptap/vue-3, @tiptap/extension-collaboration, @tiptap/extension-collaboration-caret
  • yjs >= 13

Setup

pnpm add @abraca/nuxt @abraca/dabra yjs @tiptap/core @tiptap/vue-3 @tiptap/extension-collaboration @tiptap/extension-collaboration-caret
// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@abraca/nuxt'],
  abracadabra: {
    url: 'https://your-abracadabra-server.example.com',
  }
})

Wrap your app with <AProvider> and you're live:

<template>
  <AProvider>
    <NuxtPage />
  </AProvider>
</template>

Configuration

abracadabra: {
  // Connection
  url?: string                    // Server URL (default: 'https://abra.cou.sh')
  entryDocId?: string             // Root doc ID (skips space discovery)

  // Auth
  persistAuth?: boolean           // Persist JWT in localStorage (default: true)
  authStorageKey?: string         // localStorage key (default: 'abracadabra:auth')
  auth?: {
    middleware?: boolean          // Register abracadabra-auth middleware
    globalMiddleware?: boolean    // Apply to all routes
    loginPath?: string            // Redirect target (default: '/login')
  }

  // Features (control what code is included)
  features?: {
    editor?: boolean              // TipTap editor (default: true)
    search?: boolean              // Full-text search (default: true)
    backgroundSync?: boolean      // Offline sync queue (default: true)
    renderers?: boolean           // Built-in page renderers (default: true)
    serverCache?: boolean         // Server doc-tree cache runner (default: true)
  }

  // UI
  prefix?: string                 // Component name prefix (default: '')
  locale?: Partial<AbracadabraLocale>
  docBasePath?: string            // Doc route base (default: '/doc')

  // Server-side service account (for Nitro runners)
  service?: {
    publicKey?: string            // Ed25519 public key (base64url)
    privateKey?: string           // Ed25519 private key (base64url)
  }

  debug?: boolean
}

Auto-imported Composables

| Composable | Description | |---|---| | useAbracadabra() | Full collaboration state (client, provider, identity, docs) | | useAbracadabraAuth() | Auth — login, passkey, identity management | | useAwareness() | All connected users' raw awareness states | | useAwarenessPeers() | Typed peer list with idle detection | | useAAField(key) | Per-field interaction awareness (hover, press, focus) | | useYDoc(ydoc) | Reactive Yjs primitives — useSyncedMap, useSyncedArray, useAwarenessOf, useSmoothedCursors | | useEditor(ydoc, opts) | TipTap setup with collaboration + cursor extensions | | useChildTree(docId) | Document tree scoped to a parent | | useDocumentPermissions(role) | RBAC flags (canWrite, canDelete, etc.) | | useChat(channel) | Real-time group & DM chat | | useNotifications() | Server-pushed notifications | | useSearchIndex() | Full-text search over synced docs | | useBackgroundSync() | Offline sync queue status | | useDocExport() | Export docs as markdown, HTML, or ZIP | | useDocImport() | Import .md, .txt, .html files | | useFileBlobStore() | Offline file blob cache (IndexedDB) | | useVoice() | WebRTC voice/video state | | useWindowManager() | Floating window (PiP/panel) management | | useCommandPalette() | ⌘K command palette state & commands | | useConnectionStatus() | Connection status as UI-ready label + color | | useRendererBase(docId) | Shared setup for custom page renderers | | useTrash() | Document trash (move, restore, permanent delete) | | usePasskeyAccounts() | WebAuthn passkey account management | | useFollowUser(userId) | Cursor following for pair programming |

Auto-imported Components

Core

| Component | Description | |---|---| | <AProvider> | Root wrapper — initializes SDK and syncs root doc | | <AEditor> | Full TipTap collaborative editor | | <ADocumentTree> | Hierarchical doc tree with drag-drop | | <ANodePanel> | Slide-over panel with doc metadata and children | | <ACommandPalette> | ⌘K search and command palette | | <AConnectionStatus> | Connection state badge | | <APresence> | Connected users presence indicator | | <ANotifications> | Notification center | | <AVoiceBar> | Voice/video call controls | | <ADocTypeSelect> | Page type selector | | <APermissionGuard> | Conditional render based on role | | <ARoleBadge> | Role badge (Owner, Editor, Viewer, etc.) | | <AFloatingWindow> | Floating/PiP window container | | <AWindowLayer> | Portal for floating windows |

Aware Interaction Components

Interaction components that broadcast awareness state to other users:

<AArea> <AAvatar> <AButton> <AInput> <ATextarea> <ASelect> <ACursorLabel> <AFacepile> <AUserList> <ADocBadge>

Page Renderers (requires features.renderers)

<AKanbanRenderer> <ATableRenderer> <ACalendarRenderer> <AGalleryRenderer> <AOutlineRenderer>

Server-Side Usage

Configure a service account for server-side doc access:

// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@abraca/nuxt'],
  runtimeConfig: {
    abracadabra: {
      servicePublicKey: process.env.ABRA_SERVICE_PUBLIC_KEY,
      servicePrivateKey: process.env.ABRA_SERVICE_PRIVATE_KEY,
    }
  }
})

Register custom server runners via the Nitro hook:

// server/plugins/my-runner.ts
export default defineNitroPlugin((nitro) => {
  nitro.hooks.hook('abracadabra:before-runners', (ctx) => {
    registerServerPlugin({
      name: 'my-runner',
      runners: [{
        name: 'my-background-task',
        run: async ({ provider, client }) => {
          // background work
          return () => { /* cleanup */ }
        }
      }]
    })
  })
})

Plugin System

Extend the editor, add toolbar items, slash commands, and page types:

import type { AbracadabraPlugin } from '@abraca/nuxt'

const myPlugin: AbracadabraPlugin = {
  name: 'my-plugin',
  extensions: () => [/* TipTap extensions */],
  toolbarItems: () => [/* toolbar groups */],
  suggestionItems: () => [/* slash commands */],
  pageTypes: [{ type: 'my-type', label: 'My Page', component: MyRenderer }],
  clientSetup: async (state) => { /* init */ }
}

Contribution

# Install dependencies
pnpm install

# Generate type stubs
pnpm dev:prepare

# Develop with the playground
pnpm dev

# Build
pnpm prepack

# Lint
pnpm lint

# Test
pnpm test
pnpm test:watch