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

@lilac-wysiwyg/core

v0.5.0

Published

Lilac - a smooth, modern WYSIWYG text editor built with pure TypeScript. Zero dependencies, framework-agnostic, with a clean interface and elegant typography.

Downloads

512

Readme

Lilac Editor

A smooth, modern WYSIWYG text editor built with TypeScript. Framework-agnostic core with adapters for React, Svelte, Angular, Vue, and Vanilla JS.

TypeScript Zero Dependencies Framework Agnostic

Architecture

Lilac follows an adapter pattern for maximum framework compatibility. The core functionality is isolated from framework-specific implementations, ensuring consistent behavior across all platforms.

lilac/
├── core/                    # Framework-agnostic core
│   ├── types/               # TypeScript type definitions
│   ├── plugins/              # Plugin system (emoji, table, word count)
│   ├── utils/                # Utility functions (formatting, icons)
│   ├── components/           # Core components (Editor, Toolbar)
│   └── index.ts              # Core exports
├── adapter/                  # Framework-specific adapters
│   ├── react/                # React component wrapper
│   ├── svelte/               # Svelte component
│   ├── angular/              # Angular component/directive
│   ├── vue/                  # Vue component
│   └── vanilla/              # Vanilla JS wrapper
└── docs/                     # Documentation & demos

Core Design Principles

  1. UI Instructions in Core: The core package contains all UI styling instructions to ensure consistent appearance across all framework adapters
  2. Framework-Agnostic Logic: Business logic and state management are kept framework-independent
  3. Adapter Pattern: Each framework gets its own adapter that bridges the core with framework-specific patterns

Features

  • Framework-Agnostic Core: Pure TypeScript implementation with no dependencies
  • Consistent UI: Centralized UI instructions ensure identical styling across all adapters
  • Plugin System: Extensible architecture with built-in plugins for emojis, tables, and word count
  • Rich Text Formatting: Bold, italic, underline, strikethrough, headings, lists, blockquotes, code blocks
  • Media Support: Link and image insertion with keyboard shortcuts
  • Keyboard Shortcuts: Ctrl/Cmd + B for bold, Ctrl/Cmd + I for italic, etc.
  • Undo/Redo: Full history support with 50-step undo stack
  • Theme Support: Light and dark themes with CSS custom properties
  • Accessibility: WCAG compliant with ARIA labels and keyboard navigation
  • Plugin API: Create custom plugins with toolbar buttons, keyboard shortcuts, and lifecycle hooks

Installation

Core (Vanilla JS / TypeScript)

npm install @lilac-wysiwyg/core
pnpm add @lilac-wysiwyg/core
yarn add @lilac-wysiwyg/core

Framework Adapters

# React
npm install @lilac-wysiwyg/react

# Svelte
npm install @lilac-wysiwyg/svelte

# Angular
npm install @lilac-wysiwyg/angular

# Vue
npm install @lilac-wysiwyg/vue

Quick Start

Vanilla JS / TypeScript (Core)

import { LilacEditor, injectStyles } from '@lilac-wysiwyg/core';

// Inject required styles (only needed once per page)
injectStyles();

// Create editor instance
const editor = new LilacEditor({
  container: document.getElementById('editor')!,
  toolbar: { show: true },
  placeholder: 'Start writing...',
  onChange: (content) => {
    console.log('Content:', content);
  }
});

// Get content
const content = editor.getContent();

// Set content
editor.setContent('<p>Hello World!</p>');

React

import { LilacEditor } from '@lilac-wysiwyg/react';
import '@lilac-wysiwyg/react/styles';

function App() {
  const [content, setContent] = useState('<p>Hello!</p>');

  return (
    <LilacEditor
      value={content}
      onChange={setContent}
      toolbar={{ show: true }}
      placeholder="Start writing..."
    />
  );
}

Vue 3

<template>
  <LilacEditor
    v-model="content"
    :toolbar="{ show: true }"
    placeholder="Start writing..."
  />
</template>

<script setup>
import { ref } from 'vue';
import { LilacEditor } from '@lilac-wysiwyg/vue';

const content = ref('<p>Hello!</p>');
</script>

Using Built-in Plugins

import { 
  LilacEditor, 
  injectStyles,
  pluginManager,
  wordCountPlugin,
  emojiPlugin,
  tablePlugin
} from '@lilac-wysiwyg/core';

injectStyles();

// Install plugins
pluginManager.install(wordCountPlugin);
pluginManager.install(emojiPlugin);
pluginManager.install(tablePlugin);

const editor = new LilacEditor({
  container: document.getElementById('editor')!,
  toolbar: { show: true },
  onChange: (content) => console.log('Content:', content)
});

API Reference

LilacEditor Constructor Options

| Option | Type | Default | Description | |--------|------|---------|-------------| | container | HTMLElement | required | DOM element to mount the editor | | initialContent | string | '' | Initial HTML content of the editor | | placeholder | string | 'Start writing...' | Placeholder text when editor is empty | | readOnly | boolean | false | Whether the editor is read-only | | autoFocus | boolean | false | Auto-focus editor on mount | | theme | 'light' \| 'dark' | 'light' | Editor theme | | onChange | (content: string) => void | undefined | Content change callback | | onFocus | () => void | undefined | Focus event callback | | onBlur | () => void | undefined | Blur event callback | | toolbar | ToolbarConfig | undefined | Toolbar configuration | | plugins | EditorPlugin[] | [] | Plugins to install |

LilacEditor Methods

| Method | Description | |--------|-------------| | getContent() | Get current editor HTML content | | setContent(content) | Set editor content | | focus() | Focus the editor | | blur() | Blur the editor | | undo() | Undo last change | | redo() | Redo last undone change | | setReadOnly(readOnly) | Enable/disable read-only mode | | destroy() | Clean up and remove the editor |

Toolbar Tools

| Tool | Keyboard Shortcut | |------|-----------------| | Bold | Ctrl/Cmd + B | | Italic | Ctrl/Cmd + I | | Underline | Ctrl/Cmd + U | | Strikethrough | - | | Heading 1-3 | - | | Paragraph | - | | Bullet List | - | | Ordered List | - | | Blockquote | - | | Code Block | - | | Link | Ctrl/Cmd + K | | Image | - |

Plugin System

Lilac features a powerful plugin system that allows extending the editor with custom functionality.

Built-in Plugins

  • Word Count Plugin: Displays real-time document statistics (Ctrl+Shift+W)
  • Emoji Picker Plugin: Insert emojis with an easy-to-use picker (Ctrl+Shift+E)
  • Table Inserter Plugin: Insert and manage HTML tables (Ctrl+Shift+T)

Creating Custom Plugins

import type { EditorPlugin } from '@lilac-wysiwyg/core';

export const myCustomPlugin: EditorPlugin = {
  id: 'my-custom-plugin',
  name: 'My Custom Plugin',
  version: '1.0.0',

  // Toolbar buttons
  toolbarButtons: [{
    id: 'my-button',
    icon: '<svg>...</svg>',
    label: 'My Tool',
    tooltip: 'My custom tool',
    onClick: (context) => {
      context.insertContent('<strong>Custom!</strong>');
    },
  }],

  // Keyboard shortcuts
  keyboardShortcuts: [{
    key: 'm',
    ctrlKey: true,
    action: (context) => {
      context.insertContent('<em>Shortcut!</em>');
    },
  }],

  // Lifecycle hooks
  onInstall: (context) => console.log('Installed'),
  onEditorMount: (context) => console.log('Ready'),
  onContentChange: (content, context) => {
    // React to content changes
  },
};

Customization

Themes

Override CSS custom properties to create custom themes:

.lilac-editor {
  --lilac-color-primary: #your-color;
  --lilac-color-background: #your-bg;
  --lilac-border-radius: 8px;
}

Development

# Install dependencies
pnpm install

# Build core library
pnpm build

# Watch for changes
pnpm dev

# Type check
pnpm typecheck

Documentation

Visit our GitHub Pages for complete documentation and live demos for each framework adapter.

Roadmap

  • [x] Rich text toolbar with all formatting options
  • [x] Plugin system with built-in plugins
  • [x] Emoji picker
  • [x] Table inserter
  • [x] Word count plugin
  • [x] React adapter
  • [x] Svelte adapter
  • [x] Angular adapter
  • [x] Vue adapter
  • [ ] Markdown export/import
  • [ ] Image upload and embedding
  • [ ] Find and replace
  • [ ] Mobile optimizations

Contributing

We welcome contributions! Please see our Contributing Guide for details.

License

MIT License - See LICENSE for details.

Author

Maifee Ul Asad [email protected]

Preview

preview of lilac