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

@bettaibi/react-blocknote

v0.2.2

Published

A modern, versatile rich text editor component for React applications with an elegant UI and Notion-like functionality. Supports both React 18 and React 19.

Downloads

341

Readme

React BlockNote

A modern, versatile rich text editor component for React applications with an elegant UI and Notion-like functionality.

GitHub stars

⭐ If you find this project useful or interesting, please consider giving it a star on GitHub! Your support helps us grow and improve the library for everyone.

Features

  • 🎨 Elegant & modern UI with floating toolbar and bubble menu
  • 📊 Full table support with intuitive table controls
  • 🔗 Links and image embedding
  • ✅ Task lists and checklists
  • 📝 Code blocks with syntax highlighting
  • 🔤 Rich text formatting (bold, italic, underline, etc.)
  • 📑 Comprehensive heading options (H1-H6) with dropdown menu
  • 🧮 Math formula support (KaTeX)
  • 📱 Fully responsive design that works on all devices
  • 🎯 Clean, accessible component API
  • 🔌 Markdown import/export capabilities

Installation

npm install @bettaibi/react-blocknote

Peer Dependencies

React BlockNote has a few peer dependencies that need to be installed:

npm install @radix-ui/[email protected] @radix-ui/[email protected] [email protected]

This approach minimizes the number of peer dependencies while maintaining an optimal package size.

React Version Compatibility

React BlockNote supports both React 18 and React 19. The package is designed to work seamlessly with either version without any breaking changes.

  • React 18: Full support with all features
  • React 19: Full support with all features, including the latest React improvements and concurrent features

Note: For React 19 users, the package has been specifically tested and optimized to work with Next.js 15 and other React 19 applications. All React-specific imports and type references have been updated for maximum compatibility.

Bundle Size Optimization

For detailed information on how to optimize the bundle size and performance of React BlockNote in your application, please refer to our Optimization Guide.

Usage

Regular BlockNote Component

For most use cases, you can use the pre-built BlockNote component:

import { BlockNote, BlockNoteProvider } from "@bettaibi/react-blocknote";
import "@bettaibi/react-blocknote/styles.css"; // Import styles

function MyEditor() {
  const [content, setContent] = useState("");

  return (
    // if you are using tailwind ensure adding prose classNames to the BlockNote wrapper
    <div className="lg:prose-md prose h-full max-w-full">
      <BlockNoteProvider
        value={content}
        onChange={setContent}
        placeholder="Start typing..."
        outputFormat="html" // or "markdown"
      >
        <BlockNote />
      </BlockNoteProvider>
    </div>
  );
}

Custom BlockNote with Atomic Components

For highly customized editors, you have two options for building your own editor:

Option 1: Using Atomic Components

Use pre-built atomic components with built-in functionality:

import {
  BlockNoteProvider,
  BlockNoteContent,
  BoldButton,
  ItalicButton,
  UnderlineButton,
} from "@bettaibi/react-blocknote/atomic";
import "@bettaibi/react-blocknote/styles.css";

function CustomEditor() {
  const [content, setContent] = useState("");

  return (
    <BlockNoteProvider value={content} onChange={setContent}>
      <div className="custom-editor">
        {/* Custom toolbar with atomic components */}
        <div className="toolbar">
          <BoldButton iconSize={18} />
          <ItalicButton iconSize={18} />
          <UnderlineButton iconSize={18} />
        </div>

        {/* Editor content */}
        <BlockNoteContent />
      </div>
    </BlockNoteProvider>
  );
}

Option 2: Using Custom Hooks

Use hooks to build completely custom UI components:

import {
  BlockNoteProvider,
  BlockNoteContent,
  useBlockNoteHandlers,
  useBlockNoteValues,
} from "@bettaibi/react-blocknote/atomic";
import "@bettaibi/react-blocknote/styles.css";

function CustomEditor() {
  const [content, setContent] = useState("");
  const { handleBold, handleItalic, handleUnderline } = useBlockNoteHandlers();
  const { canBold, canItalic, canUnderline } = useBlockNoteValues();

  return (
    <BlockNoteProvider value={content} onChange={setContent}>
      <div className="custom-editor">
        {/* Custom toolbar with custom buttons */}
        <div className="toolbar">
          <button className="btn" disabled={!canBold} onClick={handleBold}>
            Bold
          </button>
          <button className="btn" disabled={!canItalic} onClick={handleItalic}>
            Italic
          </button>
          <button
            className="btn"
            disabled={!canUnderline}
            onClick={handleUnderline}
          >
            Underline
          </button>
        </div>

        {/* Editor content */}
        <BlockNoteContent />
      </div>
    </BlockNoteProvider>
  );
}

Server-Side Rendering

When using SSR frameworks like Next.js, dynamically import the editor component on client-side only. This prevents Next.js from trying to use the DOMParser API during server-side rendering, which was causing the "DOMParser is not defined" error

import dynamic from "next/dynamic";

const BlockNote = dynamic(
  () => import("@bettaibi/react-blocknote").then((mod) => mod.BlockNote),
  { ssr: false }
);

Props

BlockNote Component Props

| Prop | Type | Default | Description | | ---------------- | ------- | ------- | ------------------------------------------------- | | className | string | '' | Additional CSS class for the editor container | | showToolbar | boolean | true | Whether to show the toolbar | | showBubbleMenu | boolean | true | Whether to show the bubble menu on text selection |

BlockNoteProvider Props

| Prop | Type | Default | Description | | -------------- | -------------------- | -------------------------------------------- | ------------------------------------------------------------------------- | | children | React.ReactNode | - | React children to be wrapped by the provider | | value | string | '' | The editor content as HTML or Markdown | | onChange | function | - | Callback fired when content changes. Receives the new content as argument | | placeholder | string | 'Start typing or paste a markdown file...' | Placeholder text when editor is empty | | readOnly | boolean | false | Whether the editor is in read-only mode | | outputFormat | 'html' | 'markdown' | 'html' | The format of the output in the onChange callback |

Atomic Component Props

All atomic components accept standard button props plus:

| Prop | Type | Default | Description | | ----------- | --------------- | ------- | ------------------------------------------ | | className | string | '' | Additional CSS class for the button | | iconSize | number | 16 | Size of the icon in pixels | | children | React.ReactNode | - | Custom content to replace the default icon |

Features

Text Formatting

The editor supports a wide range of text formatting options:

  • Bold, italic, underline
  • Headings (H1-H6) via convenient dropdown menu
  • Lists (ordered, unordered, task lists)
  • Text alignment (left, center, right)
  • Code blocks with syntax highlighting
  • Subscript and superscript
  • Math formulas using KaTeX
  • Contextual bubble menu that appears on text selection
  • Accessible popover components for links and images

Tables

Create and manage tables with an intuitive dropdown menu:

  • Insert tables
  • Add/delete rows and columns
  • Format table cells

Links & Images

Easily add links and images with a clean, accessible UI.

Atomic Components

When importing from @bettaibi/react-blocknote/atomic, you have access to all these atomic components:

Text Formatting Components

| Component | Description | | ----------------- | ------------------------------------ | | BoldButton | Toggle bold text formatting | | ItalicButton | Toggle italic text formatting | | UnderlineButton | Toggle underline text formatting | | StrikeButton | Toggle strikethrough text formatting | | CodeButton | Toggle inline code formatting |

Heading Components

| Component | Description | | ------------------ | -------------------------------- | | H1Button | Set heading level 1 | | H2Button | Set heading level 2 | | H3Button | Set heading level 3 | | H4Button | Set heading level 4 | | H5Button | Set heading level 5 | | H6Button | Set heading level 6 | | NormalTextButton | Convert to normal paragraph text |

List Components

| Component | Description | | ------------------- | ------------------- | | BulletListButton | Toggle bullet list | | OrderedListButton | Toggle ordered list | | TaskListButton | Toggle task list |

Block Components

| Component | Description | | ------------------ | ----------------- | | CodeBlockButton | Toggle code block | | BlockquoteButton | Toggle blockquote |

Alignment Components

| Component | Description | | ------------------- | -------------------- | | AlignLeftButton | Align text to left | | AlignCenterButton | Align text to center | | AlignRightButton | Align text to right |

History Components

| Component | Description | | ------------ | ---------------- | | UndoButton | Undo last action | | RedoButton | Redo last action |

Core Components

| Component | Description | | ------------------ | ---------------------------------------------- | | BlockNoteContent | The main editor content area | | BubbleMenu | Contextual menu that appears on text selection |

Hooks

useBlockNoteHandlers()

Returns handlers for all editor operations:

| Category | Handler | Description | | ------------------- | ----------------------- | ------------------------------- | | Text Formatting | handleBold | Toggle bold formatting | | | handleItalic | Toggle italic formatting | | | handleUnderline | Toggle underline formatting | | | handleStrike | Toggle strikethrough formatting | | | handleCode | Toggle inline code formatting | | Headings | handleHeading1 | Set heading level 1 | | | handleHeading2 | Set heading level 2 | | | handleHeading3 | Set heading level 3 | | | handleHeading4 | Set heading level 4 | | | handleHeading5 | Set heading level 5 | | | handleHeading6 | Set heading level 6 | | | handleNormalText | Convert to normal paragraph | | Lists | handleBulletList | Toggle bullet list | | | handleOrderedList | Toggle ordered list | | | handleTaskList | Toggle task list | | Blocks | handleCodeBlock | Toggle code block | | | handleBlockquote | Toggle blockquote | | Alignment | handleAlignLeft | Align text to left | | | handleAlignCenter | Align text to center | | | handleAlignRight | Align text to right | | History | handleUndo | Undo last action | | | handleRedo | Redo last action | | Media | handleImage | Insert image | | | handleLink | Insert/edit link | | Tables | handleInsertTable | Insert new table | | | handleDeleteTable | Delete current table | | | handleAddColumnBefore | Add column before current | | | handleAddColumnAfter | Add column after current | | | handleDeleteColumn | Delete current column | | | handleAddRowBefore | Add row before current | | | handleAddRowAfter | Add row after current | | | handleDeleteRow | Delete current row |

useBlockNoteValues()

Returns state values for UI control:

| Category | Value | Description | | ------------------------- | -------------------- | ------------------------------------------ | | Active State Checkers | getActiveMark | Check if a mark/node is active | | | getTextAlignState | Check if specific text alignment is active | | | TextAlign | Text alignment constants | | History | canUndo | Check if undo is available | | | canRedo | Check if redo is available | | Text Formatting | canBold | Check if bold can be applied | | | canItalic | Check if italic can be applied | | | canUnderline | Check if underline can be applied | | | canStrike | Check if strikethrough can be applied | | | canCode | Check if inline code can be applied | | Headings | canHeading1 | Check if heading 1 can be applied | | | canHeading2 | Check if heading 2 can be applied | | | canHeading3 | Check if heading 3 can be applied | | | canHeading4 | Check if heading 4 can be applied | | | canHeading5 | Check if heading 5 can be applied | | | canHeading6 | Check if heading 6 can be applied | | | canNormalText | Check if normal text can be applied | | Lists | canBulletList | Check if bullet list can be applied | | | canOrderedList | Check if ordered list can be applied | | | canTaskList | Check if task list can be applied | | Blocks | canCodeBlock | Check if code block can be applied | | | canBlockquote | Check if blockquote can be applied | | Tables | canInsertTable | Check if table can be inserted | | | canDeleteTable | Check if table can be deleted | | | canAddColumnBefore | Check if column can be added before | | | canAddColumnAfter | Check if column can be added after | | | canDeleteColumn | Check if column can be deleted | | | canAddRowBefore | Check if row can be added before | | | canAddRowAfter | Check if row can be added after | | | canDeleteRow | Check if row can be deleted |

Hook Usage Examples

// Check if bold is currently active
const isBoldActive = getActiveMark(BlockNoteMark.BOLD);

// Check if text is center-aligned
const isCenterAligned = getTextAlignState(TextAlign.CENTER);

// Check if undo operation is available
const canUndoOperation = canUndo;

Browser Support

  • Chrome (latest)
  • Firefox (latest)
  • Safari (latest)
  • Edge (latest)

Requirements

  • React 18.0.0 or higher (supports both React 18 and 19)
  • Node.js 18.0.0 or higher

Credits

This package is built on top of several amazing open-source projects: