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

quill-react-commercial

v2.0.1

Published

A production-ready Quill 2 rich text editor for React: tables, image upload & resize, code highlighting with copy, markdown shortcuts, magic URL and i18n.

Readme


Quill is an excellent open-source rich text editor with a sound data model, a clean API and a real plugin system. What it does not give you is a finished product: its release cadence has been slow, and much of the plugin ecosystem around it has gone stale. This package fills that gap — a Quill editor that is ready for production, extensible, customisable, and built with commercial use in mind.

quill-react-commercial

Features

  • Built on Quill 2, with React Hooks, full TypeScript typings and a Rollup build.
  • Images can be uploaded from disk or inserted by URL, with format and size validated up front.
  • Every image renders as Base64 first and uploads in the background; a failed upload stays clickable so the user can retry. Images can also be pasted or dragged in.
  • Images support resizing, alignment, captions and deletion, and the resize overlay is dismissed on scroll.
  • A rebuilt link tooltip with more actions than Quill's default.
  • Video embeds from YouTube, Vimeo and Bilibili: paste the page URL you copied from the address bar and it is converted to the embed URL for you. Videos stay <iframe> when the content is saved — Quill's own video format turns them back into a link.
  • Markdown shortcuts work as you type.
  • Code blocks offer language selection, one-click copy and line numbers.
  • Tables get a size picker in the toolbar, a right-click menu with more operations, and new icons.
  • Tooltips on toolbar icons, translated along with the rest of the UI.
  • Internationalisation for English, Chinese and Spanish, including Chinese font support.
  • IME-aware placeholder: the placeholder disappears as soon as you start typing Pinyin or any other composed input, instead of lingering.
  • URLs you type or paste are recognised and linked automatically.
  • Plus fixes for a long list of upstream problems: lists inside tables, image upload inside tables, ordered-list detection, deleting code and table blocks, persisting image alignment, and more.

Requirements

| | | | ----- | ----------------------- | | React | >= 16.8 (hooks) | | Node | >= 18 for development |

Install

pnpm add quill-react-commercial
# or
npm install quill-react-commercial --save
# or
yarn add quill-react-commercial

Quick start

import RichTextEditor from 'quill-react-commercial';
import 'quill-react-commercial/lib/index.css';

<RichTextEditor modules={{ table: {}, codeHighlight: true }} />;

Via UMD / CDN, the component is exposed as window.quillReactCommercial. A complete page is in example/.

<script src="https://unpkg.com/quill-react-commercial/lib/index.js"></script>

Usage

All props are typed — your editor will show the full definitions on hover.

modules — required, object

Every key can be set to false to turn that module off.

{
  codeHighlight?: true,
  table?: {
    operationMenu?: {
      insertColumnRight?: {
        text: 'Insert Column Right',
      }
    }, // usually not needed
    backgroundColors?: {
      colors?: ['#4a90e2', '#999'], // table cell background; default: ['#dbc8ff', '#6918b4', '#4a90e2', '#999', '#fff']
      text?: 'Background Colors',   // default: 'Background Colors'
    },
    toolBarOptions?: {
      dialogRows?: 3,    // default: 9
      dialogColumns?: 4, // default: 9
      i18n?: 'en',
    }, // the size picker shown when you click "table" in the toolbar
  }, // default: false
  imageResize?: true, // default: true
  imageDrop?: true,   // default: true
  magicUrl?: true,    // auto-detect URLs and emails and wrap them in a link; default: true
  markdown?: true,    // convert markdown syntax to rich text as you type; default: true
  link?: true,        // default: true
  video?: true,       // video embed button; default: true
                      // or { width?: '100%', height?: '360' } for the inserted iframe
  imageHandler: {
    imgUploadApi?: (formData: FormData) => Promise<string>; // upload endpoint; resolve with the image URL
    uploadSuccCB?: (data: unknown) => void; // called on success
    uploadFailCB?: (error: unknown) => void; // called on failure
    imgRemarkPre?: 'Fig. '; // prefix for the image caption; the user can delete it
    maxSize?: 2; // max size for a local upload, in MB; default: 5
    imageAccept?: string; // accepted types; default: 'image/png, image/gif, image/jpeg, image/bmp, image/x-icon, image/webp'
  },
  toolbarOptions?: [][]; // pick and order the toolbar controls yourself
}

Defaults for modules.table.operationMenu:

{
  insertColumnRight: { text: 'Insert Column Right' },
  insertColumnLeft:  { text: 'Insert Column Left' },
  insertRowUp:       { text: 'Insert Row Above' },
  insertRowDown:     { text: 'Insert Row Below' },
  mergeCells:        { text: 'Merge Selected Cells' },
  unmergeCells:      { text: 'Unmerge Cells' },
  deleteColumn:      { text: 'Delete Columns' },
  deleteRow:         { text: 'Delete Rows' },
  deleteTable:       { text: 'Delete Table' },
}

table-en

If modules.imageHandler is omitted, inserted images are converted to Base64 and stored inline in the Delta.

image

modules.toolbarOptions follows Quill's own format — see the toolbar docs:

const toolbarOptions = [
  ['undo', 'redo', 'clean'],
  [{ font: ['wsYaHei', 'songTi', 'serif', 'arial'] }, { size: ['12px', '14px', '18px', '36px'] }],
  [{ color: [] }, { background: [] }],
  ['bold', 'italic', 'underline', 'strike'],
  [
    { list: 'ordered' },
    { list: 'bullet' },
    { list: 'check' },
    { indent: '-1' },
    { indent: '+1' },
    { align: [] },
  ],
  [
    'blockquote',
    'code-block',
    'link',
    'image',
    'video',
    { script: 'sub' },
    { script: 'super' },
    'table',
    'divider',
  ],
];

Languages offered by modules.codeHighlight — override the list to change it, or open a PR to add one:

[
  { key: 'plain', label: 'Plain' },
  { key: 'javascript', label: 'Javascript' },
  { key: 'java', label: 'Java' },
  { key: 'python', label: 'Python' },
  { key: 'cpp', label: 'C++/C' },
  { key: 'csharp', label: 'C#' },
  { key: 'php', label: 'PHP' },
  { key: 'sql', label: 'SQL' },
  { key: 'json', label: 'JSON' },
  { key: 'bash', label: 'Bash' },
  { key: 'go', label: 'Go' },
  { key: 'objectivec', label: 'Object-C' },
  { key: 'xml', label: 'Html/xml' },
  { key: 'css', label: 'CSS' },
  { key: 'ruby', label: 'Ruby' },
  { key: 'swift', label: 'Swift' },
  { key: 'scala', label: 'Scala' },
];

Other props

| Prop | Type | Default | Description | | ------------- | ----------------------------------------------------- | -------------- | ------------------------------------------------------- | | placeholder | string | locale default | Placeholder shown while the editor is empty. | | getQuill | (quill: Quill, uploadedImgsList?: string[]) => void | — | Receives the Quill instance once it is ready. | | content | Delta \| string | — | Initial content, as a Delta or an HTML string. | | readOnly | boolean | false | Renders the editor disabled. | | onChange | (delta: Delta, old: Delta) => void | — | Fires on user edits only, not on programmatic writes. | | onFocus | (range?: Range) => void | — | Fires when the editor gains focus. | | onBlur | (oldRange?: Range) => void | — | Fires when the editor loses focus. | | onSave | () => void | — | Fires on Ctrl/Cmd + S. | | i18n | 'en' \| 'zh' \| 'es' | 'en' | UI language. | | style | CSSProperties | — | Applied to the editor container. | | theme | 'snow' \| 'bubble' | 'snow' | Quill theme. |

getQuill

The instance exposes the full Quill API:

const quill = useRef(null);
const getQuill = (quillIns) => {
  quill.current = quillIns;
};

const content = quill.current?.getContents(); // the editor content, as a Delta
const text = quill.current?.getText(); // the editor content, as plain text

content

// as a Delta
<RichTextEditor
  modules={{ table: {}, codeHighlight: true }}
  getQuill={getQuill}
  content={JSON.parse('{"ops":[{"insert":"Hello quill-react-commercial!\\n"}]}')}
/>

// as an HTML string
<RichTextEditor
  modules={{ table: {}, codeHighlight: true }}
  getQuill={getQuill}
  content={'<h1>Hello quill-react-commercial!</h1>'}
/>

FAQ

How do I change the code highlighting theme?

The default is highlight.js's xcode theme. Import another one:

import 'highlight.js/styles/darcula.css';

Or link it:

<link
  rel="stylesheet"
  href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/styles/androidstudio.min.css"
/>

Development

pnpm install
pnpm example     # build the demo bundle, then open example/index.html
pnpm test        # vitest
pnpm lint        # eslint
pnpm typecheck   # tsc --noEmit
pnpm build       # bundle + type declarations
  • Editing the editor's own JS/Less hot-reloads, but the browser still needs a refresh.
  • Editing example/app.js does not re-run Babel — run pnpm example again.
  • Since 1.3.7 the build uses Rollup, which avoids the redundant SVG configuration the earlier tsc + webpack pipeline produced.

Bug reports and pull requests are welcome — see CONTRIBUTING.md for the flow.

License

ISC © ludejun