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

richtext-core-svelte

v1.3.0

Published

[![npm version](https://img.shields.io/npm/v/richtext-core-svelte.svg)](https://www.npmjs.com/package/richtext-core-svelte) [![npm downloads](https://img.shields.io/npm/dw/richtext-core-svelte.svg)](https://www.npmjs.com/package/richtext-core-svelte) [![B

Readme

richtext-core-svelte

npm version npm downloads Bundle Size

Plug and Play AI Rich Text Editor for Svelte 5 — built on Lexical with dark mode support and API key authentication.

This is the official Svelte wrapper for the Eddyter editor. It exposes the editor as an idiomatic Svelte 5 component (<Eddyter />) using runes, while internally calling richtext-core-sdk under the hood.

Eddyter Editor

Resources

Installation

npm install richtext-core-svelte
# or
yarn add richtext-core-svelte
# or
pnpm add richtext-core-svelte

Compatibility

| Requirement | Version | |-------------|---------| | Svelte | 5.x | | Node.js | 16+ | | Browsers | Evergreen (Chrome, Edge, Firefox, Safari) |

The wrapper depends on richtext-core-sdk, which bundles React + ReactDOM internally. Your Svelte app does not need to install or configure React.

Quick Start

1. Get your API key

  1. Create an account at eddyter.com
  2. Navigate to License Keys in your dashboard
  3. Copy your API key

2. Use the component

<script lang="ts">
  import { Eddyter } from 'richtext-core-svelte';

  const apiKey = import.meta.env.VITE_EDITOR_API_KEY as string;

  let html = $state('<p>Start writing...</p>');

  const currentUser = {
    id: 'user-123',
    name: 'John Doe',
    email: '[email protected]',
    avatar: 'https://example.com/avatar.jpg', // optional
  };
</script>

<Eddyter
  {apiKey}
  value={html}
  user={currentUser}
  mentionUserList={['Alice', 'Bob', 'Charlie']}
  onChange={(next) => (html = next)}
  onReady={() => console.log('Editor ready!')}
  onAuthError={(err) => console.error('Auth failed:', err)}
/>

Styles are imported automatically by the wrapper — you don't need to import richtext-core-sdk/style.css manually.

Features

Text & Formatting

  • Bold, italic, underline, strikethrough, subscript, superscript
  • Text color and background highlight with color picker
  • 20+ font families with adjustable font sizes
  • Text alignment (left, center, right, justify)
  • Line height and letter spacing controls

Lists & Structure

  • Bullet lists, numbered lists (decimal, alpha, roman)
  • Interactive checklists with strikethrough
  • Headings (H1-H6), blockquotes
  • Horizontal rules

Tables

  • Insert/delete rows and columns, merge cells
  • Drag-to-resize columns and rows
  • Header row styling, row striping
  • Right-click context menu for table actions

Media

  • Image upload with drag-drop and 8-point resize handles
  • Video embed with drag-drop and paste support
  • File attachments (downloadable files)
  • Link insertion with floating editor
  • Automatic link preview on hover
  • Rich embeds for external content (YouTube, etc.)

AI Features (Premium)

  • AI Chat assistant for content help
  • Smart autocomplete (AI-powered text suggestions)
  • Real-time grammar check and corrections
  • Text enhancement (improve, shorten, expand)
  • Tone adjustment (formal, casual, professional)
  • AI image generation from text prompts

Advanced

  • Slash commands (/ for quick formatting)
  • @Mentions with customizable user list
  • Inline comments with bubble UI and sidebar
  • Note panels (info, warning, error, success)
  • Code blocks with syntax highlighting
  • Interactive charts
  • Digital signature capture
  • Voice input / transcription
  • Export to PDF
  • HTML view toggle
  • Drag-and-drop block reordering
  • Markdown shortcuts

Dark Mode

The editor automatically detects your app's theme:

  • Checks for dark class on <html> or <body>
  • Falls back to prefers-color-scheme: dark system preference
  • Or pass darkMode={true} / darkMode={false} explicitly — changes apply at runtime without remounting.
<script lang="ts">
  import { Eddyter } from 'richtext-core-svelte';
  let isDark = $state(false);
</script>

<Eddyter apiKey="your-api-key" darkMode={isDark} />

Preview Mode

Display saved editor content in read-only mode with interactive features:

<Eddyter
  apiKey="your-api-key"
  mode="preview"
  value={savedHtml}
  containerClass="my-preview-styles"
  onPreviewClick={switchToEditMode}
/>

API Reference

<Eddyter>

The main editor component.

Props

| Prop | Type | Required | Description | |------|------|----------|-------------| | apiKey | string | Yes | Your Eddyter license key | | value | string | No | Initial HTML content. Listen to onChange for updates | | user | EddyterCurrentUser | No | Current user for comments / mentions. Defaults to anonymous | | mode | 'edit' \| 'preview' | No | Editor mode (default: 'edit') | | darkMode | boolean | No | true/false. Omit to auto-detect host's .dark class | | customVerifyKey | (key: string) => Promise<EddyterApiResponse> | No | Use your own backend to validate the API key | | mentionUserList | string[] | No | Names that appear in @mention suggestions | | defaultFontFamilies | string[] | No | Font family names for the font selector | | className | string | No | CSS class applied to the outermost editor wrapper | | containerClass | string | No | CSS class applied to the preview container (only used when mode: 'preview') | | contentClass | string | No | CSS class applied to the editable content area | | floatingToolbarClass | string | No | CSS class applied to the floating toolbar and its portal container | | style | Record<string, string \| number> | No | Inline style object applied to the wrapper | | toolbar | EddyterToolbarConfig | No | Toolbar behavior (default: { mode: 'sticky', offset: 20, zIndex: 1000 }) | | editor | EddyterEditorOptions | No | Editor container options (maxHeight) | | enableReactNativeBridge | boolean | No | Force-enable RN WebView bridge messaging |

Callback Props

Svelte 5 uses callback props instead of event dispatching:

| Prop | Type | Fires when | |------|------|------------| | onChange | (html: string) => void | Editor content changes (debounced) | | onReady | () => void | Editor finished mounting and authenticated | | onAuthSuccess | () => void | API key validated successfully | | onAuthError | (error: string) => void | API key validation failed | | onFocus | () => void | Editor gained focus (React Native bridge) | | onBlur | () => void | Editor lost focus (React Native bridge) | | onHeightChange | (height: number) => void | Editor content height changes (React Native bridge) | | onPreviewClick | () => void | User clicks anywhere inside the preview (e.g. to open edit mode) |

Exposed Methods (via bind:this)

interface ExposedApi {
  /** Returns the underlying SDK instance (or null before mount) */
  getInstance(): EddyterInstance | null;
}
<script lang="ts">
  import { Eddyter } from 'richtext-core-svelte';

  let editor: Eddyter;

  function toggleDarkMode() {
    editor.getInstance()?.update({ darkMode: true });
  }
</script>

<Eddyter bind:this={editor} apiKey="your-api-key" />
<button onclick={toggleDarkMode}>Dark mode</button>

Supporting Types

import type {
  EddyterInstance,
  EddyterCurrentUser,
  EddyterToolbarConfig,
  EddyterEditorOptions,
  EddyterApiResponse,
} from 'richtext-core-sdk';

interface EddyterCurrentUser {
  id: string;
  name: string;
  email?: string;
  avatar?: string;
}

interface EddyterApiResponse {
  success: boolean;
  message: string;
  data?: unknown;
}

interface EddyterToolbarConfig {
  mode?: 'sticky' | 'static';
  offset?: number;
  zIndex?: number;
}

interface EddyterEditorOptions {
  maxHeight?: string | number;
}

Toolbar Configuration

<Eddyter
  apiKey="your-api-key"
  toolbar={{ mode: 'sticky', offset: 64, zIndex: 1200 }}
/>

Modes:

  • mode: 'sticky' -> toolbar detaches/sticks while scrolling and applies offset + zIndex
  • mode: 'static' -> toolbar stays attached and ignores offset + zIndex even if provided

Defaults: { mode: 'sticky', offset: 20, zIndex: 1000 }.

In static mode, if you want only the editor content area to scroll, pass a maxHeight using editor:

<Eddyter
  apiKey="your-api-key"
  toolbar={{ mode: 'static' }}
  editor={{ maxHeight: 600 }}
/>

Examples

Basic Editor

<script lang="ts">
  import { Eddyter } from 'richtext-core-svelte';
</script>

<Eddyter apiKey="your-api-key" onReady={() => console.log('Ready!')} />

Editor with State Management & Save

<script lang="ts">
  import { Eddyter } from 'richtext-core-svelte';

  let html = $state('<p>Start writing...</p>');

  async function handleSave() {
    await fetch('/api/save', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ content: html }),
    });
  }
</script>

<Eddyter apiKey="your-api-key" value={html} onChange={(next) => (html = next)} />
<button onclick={handleSave}>Save</button>

Comments & Mentions

<script lang="ts">
  import { Eddyter } from 'richtext-core-svelte';

  const currentUser = {
    id: 'u-1',
    name: 'Jane Doe',
    email: '[email protected]',
  };
</script>

<Eddyter
  apiKey="your-api-key"
  user={currentUser}
  mentionUserList={['Alice', 'Bob', 'Charlie']}
/>

Custom API Key Verification

<script lang="ts">
  import { Eddyter } from 'richtext-core-svelte';

  async function customVerifyKey(apiKey: string) {
    try {
      const res = await fetch('/api/verify-key', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ apiKey }),
      });
      const data = await res.json();
      return { success: data.valid, message: data.message || 'Verified' };
    } catch {
      return { success: false, message: 'Verification failed' };
    }
  }
</script>

<Eddyter apiKey="your-api-key" {customVerifyKey} />

Theme Toggle Without Remount

<script lang="ts">
  import { Eddyter } from 'richtext-core-svelte';

  let isDark = $state(false);
</script>

<button onclick={() => (isDark = !isDark)}>Toggle theme</button>
<Eddyter apiKey="your-api-key" darkMode={isDark} />

Static Toolbar with Scrollable Content

<Eddyter
  apiKey="your-api-key"
  toolbar={{ mode: 'static' }}
  editor={{ maxHeight: '420px' }}
/>

Migration

If you are upgrading from an earlier release, two legacy props were removed because they targeted SDK options that never reached the underlying editor:

| Old prop | New prop | Status | |----------|----------|--------| | previewClass | containerClass | Removed — old value was a no-op | | editorClass | contentClass | Removed — old value was a no-op | | — | floatingToolbarClass | New — style the floating toolbar / portal |

- <Eddyter apiKey={key} previewClass="p" editorClass="c" />
+ <Eddyter apiKey={key} containerClass="p" contentClass="c" />

Troubleshooting

| Symptom | Fix | |---------|-----| | Editor renders but toolbars look broken | Make sure your bundler isn't tree-shaking richtext-core-sdk/style.css. The wrapper imports it automatically. | | Theme does not switch | Bind darkMode={isDark} — it updates the editor without remounting. | | API key errors | Confirm the key in your env vars and check the network tab for the verification request. | | Content updates don't reach parent state | Pass an onChange callback and update your $state from there. |

License

Eddyter is proprietary software.

  • Free for evaluation and non-commercial use
  • Commercial use requires a paid license
  • SaaS, redistribution, and competing products are prohibited without permission

For commercial licensing, visit eddyter.com