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

inkflow

v0.1.4

Published

A premium, lightweight, and framework-agnostic WYSIWYG rich text editor with a sophisticated Slate & Indigo design. Highly customizable and optimized for React, Next.js, and Vanilla TypeScript.

Readme

Inkflow: The Premium WYSIWYG Rich Text Editor for Modern Web Apps ✍️

NPM Version NPM Downloads Status License ESM Only

A premium, ultra-lightweight, and framework-agnostic WYSIWYG rich text editor built entirely with Vanilla TypeScript — featuring a polished Slate & Indigo design, XSS protection, dynamic toolbar positions, and first-class support for React, Next.js, and modern web apps.

[!NOTE] v0.1.0 — Early Experiment: This is the initial public release of Inkflow. The core API is functional and actively being refined. Community feedback is warmly welcomed! 🚀


🖼 Editor Preview

Inkflow Editor Preview


💡 What is WYSIWYG?

WYSIWYG stands for "What You See Is What You Get". Unlike markdown or code editors, what you type in Inkflow — bold text, centered headings, interactive tables — is exactly how it appears when published. It bridges the gap between editing and the final result, making rich-text creation intuitive and predictable.


🎮 Live Demo

Try the Interactive React Demo on StackBlitz: ▶ Run Demo on StackBlitz


🚀 Why Choose Inkflow?

Inkflow is designed for developers who need a high-performance, secure, and beautiful editor without the complexity of traditional rich-text frameworks.

  • 🎨 Sophisticated Design: Built with a native Slate & Indigo theme, Inkflow feels premium out-of-the-box.
  • 🔒 Security-First: Every keystroke path is hardened with DOMPurify, making it one of the most secure editors available.
  • ⚛️ Framework Ready: Seamlessly integrates with React, Next.js (SSR-safe), and TypeScript.
  • 📏 Ultra-Lightweight: At just ~28kB, it won't bloat your bundle size.

✨ Features

| Feature | Description | | :------------------------ | :-------------------------------------------------------- | | 🪶 ~28kB packed | Microscopic footprint — incredibly fast initial load | | 🔒 Security 9.8/10 | Hard-coded XSS sanitization via DOMPurify | | ⚡ Pure ESM | Zero CJS bloat, optimized for Vite, Webpack 5+ | | 🎯 Framework Agnostic | React, Next.js, Vue, Angular, Svelte | | 🌑 Dark Mode | Sophisticated built-in dark theme | | 📐 Toolbar Positions | Top, Bottom, Left, Right, Floating | | 📊 Table Editor | Native insert & style interactive HTML tables | | 😊 Emoji Picker | Searchable emoji library (lazy-loaded on demand) | | 🖼 Image Pipeline | Drag-and-drop, WebP compression, resize handles, captions | | 🧙 Magic Format | Typography & Accent themes with one-click reset | | 📋 Smart Paste | Auto-formats pasted HTML into clean rich text | | 🧹 Auto-Save | Configurable auto-save with visual "Saved at..." status |


🏗 Architecture

Inkflow is built with Vanilla TypeScript and zero runtime dependencies (only dompurify for security). Key internals:

  • CoreEditor — manages the contenteditable element, selection, history, and auto-save
  • Toolbar — dynamic toolbar with granular item control and 5 position modes
  • SelectionManager — cross-browser selection and range utilities
  • HistoryManager — undo/redo with snapshot diffing
  • ImageManager — client-side WebP compression, upload adapters, and resize handles

🛡 Security & XSS Protection

Inkflow takes security seriously with a 9.8/10 internal audit score:

  • Auto-sanitizes all pasted content and API inputs via DOMPurify
  • Blocks javascript:, data:, and vbscript: URI schemes
  • Forces rel="noopener noreferrer" on every link
  • Eliminates innerHTML usage in all UI rendering (zero-trust approach)
  • Normalizes content after every structural change with a final sanitization pass

📦 Installation

npm install inkflow

🚀 Quick Start

Vanilla JS / TypeScript

import { InkflowEditor } from "inkflow";
import "inkflow/style";

const container = document.getElementById("editor");
const editor = new InkflowEditor(container, {
  placeholder: "Type something beautiful...",
  autofocus: true,
  showStatus: true,
  toolbarItems: ["bold", "italic", "heading", "table", "link"],
});

React

In React Strict Mode, components mount twice in development. Always call destroy() in the cleanup function.

import { useEffect, useRef } from "react";
import { InkflowEditor } from "inkflow";
import "inkflow/style";

export default function App() {
  const containerRef = useRef<HTMLDivElement>(null);
  const editorRef = useRef<InkflowEditor | null>(null);

  useEffect(() => {
    if (containerRef.current && !editorRef.current) {
      editorRef.current = new InkflowEditor(containerRef.current, {
        placeholder: "Start writing...",
      });
    }
    return () => {
      editorRef.current?.destroy();
      editorRef.current = null;
    };
  }, []);

  return <div ref={containerRef} />;
}

Next.js

"use client";
import { useEffect, useRef } from "react";
import { InkflowEditor } from "inkflow";
import "inkflow/style";

export default function MyEditor() {
  const containerRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (!containerRef.current) return;
    const editor = new InkflowEditor(containerRef.current, {
      onSave: (html) => console.log(html),
    });
    return () => editor.destroy(); // Crucial for HMR and Strict Mode
  }, []);

  return <div ref={containerRef} className="editor-shell" />;
}

⚙️ Configuration Options

| Option | Type | Default | Description | | :------------------- | :--------- | :---------- | :------------------------------------------------------------- | | placeholder | string | undefined | Placeholder text when the editor is empty | | autofocus | boolean | false | Auto-focus the editor on init | | dark | boolean | false | Enable dark mode theme | | showStatus | boolean | true | Show/hide the "Saved at..." status bar | | showCharCount | boolean | false | Show character/word count metrics | | toolbarItems | string[] | all | Array of tool IDs to display | | toolbarPosition | string | 'top' | Toolbar position: top, bottom, left, right, floating | | onSave | function | undefined | Callback when content is saved ((html: string) => void) | | onSaving | function | undefined | Callback when auto-save is triggered | | autoSaveInterval | number | 1000 | Debounce delay in ms before auto-save fires | | imageEndpoints | object | undefined | Custom upload endpoint: { upload: string } | | cloudinaryFallback | object | undefined | Cloudinary fallback: { cloudName, uploadPreset } | | maxImageSizeMB | number | 5 | Max image size in MB (enforced pre and post compression) |


🛠 API Methods

| Method | Description | | :-------------------------------- | :------------------------------------------------------------ | | destroy() | Required on unmount. Cleans up DOM, listeners, and memory | | getHTML() | Returns sanitized HTML string of the editor content | | setHTML(html) | Programmatically sets editor content | | focus() | Forces focus onto the editor | | setDarkMode(boolean) | Dynamically toggle dark mode | | insertTable(rows, cols) | Programmatically insert a table | | insertImage(url, id, isLoading) | Insert an image with optional loading state | | getToolbar() | Returns the Toolbar instance |


🔧 Toolbar Positions

Inkflow supports 5 toolbar layout modes:

new InkflowEditor(container, {
  toolbarPosition: 'top'      // Default — above the editor
  toolbarPosition: 'bottom'   // Below the editor
  toolbarPosition: 'left'     // Vertical sidebar, left
  toolbarPosition: 'right'    // Vertical sidebar, right
  toolbarPosition: 'floating' // Context-aware floating toolbar
});

💡 Troubleshooting

Seeing duplicate editors or toolbars?

  1. React Strict Mode: Ensure editor.destroy() is called in the useEffect cleanup.
  2. Missing cleanup: The editor injects elements into the DOM — always destroy on unmount.

Editor not initializing in Next.js?

  • Make sure the component has "use client" and wraps initialization inside useEffect.

📝 Changelog

v0.1.4 — UI Alignment Patch (current)

  • 📏 Forced Left-Alignment: Explicitly set text-align: left and justify-content: flex-start in the library's core CSS. This prevents the editor from inheriting unwanted centering styles from the host application environment.
  • 🛠 UI Stability: Ensured that toolbar items and editable areas maintain consistent positioning across different screen sizes and parent container configurations.

v0.1.3 — Style & Stability Patch

  • 🎨 Fixed Styling Issue: Resolved a critical issue where the editor would appear unstyled due to incorrect CSS export paths in package.json. Corrected the path to inkflow/dist/inkflow.css.

v0.1.0 — Initial Experiment

  • 🎉 First public release of Inkflow Editor under the inkflow package name
  • Toolbar positions: top, bottom, left, right, floating
  • Premium Table UI with rounded corners, zebra stripes, and interactive states
  • Magic Format 2.0: Typography & Accents themes with a dedicated Reset button
  • Refined vertical sidebar toolbars (76px) with pill-shaped controls
  • Hardened paste sanitization to prevent character limit bypasses
  • ~28kB packed weight, Pure ESM architecture

📄 License

MIT © Anuj Nainwal