@alggtta/editor
v6.6.1
Published
Alggtta Editor with Tiptap 3.x and DaisyUI 5
Maintainers
Readme
@alggtta/editor
React/TypeScript Notion-style editor built on Tiptap 3, Tailwind CSS v4, and DaisyUI 5.
@alggtta/editor (core-first since v3) keeps the default package focused on the core editor. Heavy features such as database blocks, Mermaid, AI, and export helpers are available through opt-in subpath imports.
Install
npm install @alggtta/editor --save-exactInstall peer dependencies in your app:
npm install react react-dom @tiptap/[email protected] @tiptap/[email protected] @tiptap/[email protected] @tiptap/[email protected] @tiptap/[email protected] [email protected] [email protected] --save-exactKeep all Tiptap singleton peers on exactly 3.27.4. Tiptap packages require
matching patch versions; 3.28.x and later are also excluded because of the known
React NodeView caret and duplicate-core regressions. @tiptap/y-tiptap uses its
independent 3.0.8 release line. [email protected] and [email protected] are also
required singleton peers because the main entry eagerly links the collaboration
extension graph.
Yarn Classic 1.x consumers must use the same exact peers with --ignore-optional:
yarn add --ignore-optional --exact @alggtta/editor react react-dom @tiptap/[email protected] @tiptap/[email protected] @tiptap/[email protected] @tiptap/[email protected] @tiptap/[email protected] [email protected] [email protected]That flag skips every optional dependency in this Yarn install. Its important
effect in this graph is preventing the redundant newer menu copies resolved
from @tiptap/react's optional ranges; the two exact root menu packages above
keep menu functionality available. Explicitly install any other optional
package your app needs. This workaround is specific to Yarn Classic 1.x, not a
general Yarn Modern requirement.
TypeScript
Minimum TypeScript: >=5.3
typescript is declared as an optional peer dependency — JavaScript consumers need
nothing. TypeScript consumers need 5.3 or newer because the CommonJS declarations served
to exports["*"].require.types (dist/**/*.d.cts) annotate their type-only edges to
ESM-only packages (yjs, @tanstack/react-table) with
with { "resolution-mode": "import" }. TypeScript only parses that attribute from 5.3
onward; on 5.2 and older it is a syntax error (TS1005) that skipLibCheck: true
does not suppress, so the CJS type surface fails to load entirely.
Measured: 5.2.2 → TS1005 (tsc exit 2, with or without skipLibCheck); 5.3.2 → clean.
The ESM declarations (dist/**/*.d.ts) carry no such attribute and work on older
compilers — the floor applies only to the require condition.
Production usage requires an Alggtta token. Localhost development still works with a token-shaped value such as tok_dev.
Basic Usage
import { AlggttaEditor } from '@alggtta/editor'
import '@alggtta/editor/styles.css'
export function EditorPage() {
return (
<AlggttaEditor
token={process.env.NEXT_PUBLIC_ALGGTTA_TOKEN ?? ''}
content="<h1>Hello</h1><p>Type / for commands.</p>"
onUpdate={({ editor, json, html, text }) => {
console.log({ json, html, text })
}}
/>
)
}Next.js App Router
Use the editor from a client component.
'use client'
import { AlggttaEditor } from '@alggtta/editor'
import '@alggtta/editor/styles.css'
export default function EditorClient() {
return (
<AlggttaEditor
token={process.env.NEXT_PUBLIC_ALGGTTA_TOKEN ?? ''}
variant="document"
onUpdate={({ json }) => {
void fetch('/api/document', {
method: 'POST',
body: JSON.stringify(json),
})
}}
/>
)
}Vite / CRA / React
import { AlggttaEditor } from '@alggtta/editor'
import '@alggtta/editor/styles.css'
export function App() {
return (
<AlggttaEditor
token={import.meta.env.VITE_ALGGTTA_TOKEN}
placeholder="Write something..."
/>
)
}Visual Variants
Use variant to fit the editor into different layouts:
<AlggttaEditor token={token} variant="document" />
<AlggttaEditor token={token} variant="embedded" />
<AlggttaEditor token={token} variant="bare" />document: default document canvas with comfortable padding.embedded: compact shell for dashboards and admin panels.bare: minimal wrapper when your app owns the layout.
License UI
token is required. verifyEndpoint defaults to https://cdn.alggtta.com.
<AlggttaEditor
token={token}
licenseFallback={({ error }) => (
<div role="alert">Editor license check failed: {error}</div>
)}
/>Subpath Imports
import { useAlggttaEditor, useAutosave } from '@alggtta/editor/headless'
import { definePlugin, resolvePlugins } from '@alggtta/editor/plugin'
import { createDatabaseExtensions, databaseSlashCommands } from '@alggtta/editor/database'
import { createMermaidExtensions, mermaidSlashCommands } from '@alggtta/editor/mermaid'
import { createAIExtensions, getDocumentContext } from '@alggtta/editor/ai'
import { markdownToHtml, htmlToMarkdown } from '@alggtta/editor/export'
import { LicensedGate, useLicenseVerification } from '@alggtta/editor/license'
import { useComments, CommentSidebar } from '@alggtta/editor/comments'
import { createCollaborationExtensions, usePresence } from '@alggtta/editor/collab'
import { UniversalEditor } from '@alggtta/editor/legacy'The main entry includes the core blocks: paragraph, headings 1-3, lists, task list, quote, divider, link, highlight, image, table, code block, slash menu, bubble menu, and drag handle. Pass preset="full" to also mount the advanced blocks (callout, toggle, columns, embed, file attachment, mention, wiki link, comments, find/replace, synced block) and their slash commands. Math (KaTeX) is excluded from full to keep the bundle lean — it's a heavy optional peer; add MathExtension/InlineMathExtension from @alggtta/editor/legacy via extensionConfig.customExtensions if you need it.
The main entry also exports the framework-agnostic mount(el, props) factory, the <alggtta-editor> Web Component (defineAlggttaEditorElement()), and the getWikiLinks(doc) link-enumeration API. To keep the core lean, the heavier page-chrome components (VersionHistory, PageMeta, TableOfContents) live in @alggtta/editor/legacy, and the version/migration utilities (createPageVersionFromAITransaction, MigrationRegistry) in @alggtta/editor/headless.
Embed anywhere (no React app)
The mount(el, props) factory and <alggtta-editor> Web Component work from any
stack. The bundle served from cdn.alggtta.com keeps React external, so load the
react / react-dom UMD globals first, then the editor. Every CDN asset is
token-gated, so pass ?token= on both the script and the stylesheet — a
<link> / <script> tag can't send an Authorization header (no token → 401;
invalid, expired, or wrong-domain token → 403):
<script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
<link rel="stylesheet" href="https://cdn.alggtta.com/editor.css?token=YOUR_TOKEN" />
<script src="https://cdn.alggtta.com/editor.umd.js?token=YOUR_TOKEN"></script>
<alggtta-editor token="YOUR_TOKEN" preset="full"></alggtta-editor>
<!-- or imperatively: window.AlggttaEditor.mount('#el', { token, preset: 'full' }) -->From npm you can call
mount/defineAlggttaEditorElementdirectly (React resolved as a peer) — no UMD globals needed.
Building a wiki? The editor ships the primitives (
[[/@triggers,getWikiLinks, autosave). Durable storage — backlinks, full-text search, and versions — is handled by the private companion package@alggtta/wiki-store, provided to licensees on request (contact https://alggtta.com).
Optional entries may require their matching peer dependencies, for example @tanstack/react-table@^9.1.2 for database blocks and mermaid for Mermaid diagrams. The database subpath uses TanStack Table v9's feature-explicit API and is not compatible with v8. Export/import UI loads html2pdf.js and mammoth only when the PDF or DOCX actions are used.
Optional Feature Composition
import { AlggttaEditor } from '@alggtta/editor'
import { createDatabaseExtensions, databaseSlashCommands } from '@alggtta/editor/database'
<AlggttaEditor
token={token}
extensionConfig={{
customExtensions: createDatabaseExtensions(),
customSlashCommands: databaseSlashCommands,
}}
/>Export UI is also opt-in. Import the dropdown from /export and inject it into the editor footer:
import { AlggttaEditor } from '@alggtta/editor'
import { ExportDropdown, exportSlashCommands } from '@alggtta/editor/export'
<AlggttaEditor
token={token}
extensionConfig={{
customSlashCommands: exportSlashCommands,
}}
renderFooterControls={({ editor, allowedFeatures }) =>
allowedFeatures.includes('*') || allowedFeatures.includes('export')
? <ExportDropdown editor={editor} />
: null
}
/>Only expose optional commands for features you actually register or render.
Plugin Development
Use the lightweight /plugin entry to bundle custom Tiptap extensions and
slash commands into a mount-time plugin. Plugin command ids and extension names
must be unique; command ids also cannot collide with ids declared by the host's
customSlashCommands.
import { AlggttaEditor } from '@alggtta/editor'
import { ClockIcon } from '@heroicons/react/24/outline'
import { Extension, definePlugin } from '@alggtta/editor/plugin'
import '@alggtta/editor/styles.css'
const timestampPlugin = definePlugin({
id: 'com.example.timestamp',
version: '1.0.0',
extensions: [Extension.create({ name: 'exampleTimestampBehavior' })],
slashCommands: [
{
id: 'com.example.timestamp.insert',
title: 'Insert timestamp',
description: 'Insert the current time',
icon: ClockIcon,
command: (editor) => {
editor.chain().focus().insertContent(new Date().toISOString()).run()
},
},
],
})
export function PluginEditor() {
return (
<AlggttaEditor
token={import.meta.env.VITE_ALGGTTA_TOKEN}
extensionConfig={{ plugins: [timestampPlugin] }}
/>
)
}The plugin set is fixed when the editor is created; remount to change the
schema. External plugin packages must keep React and all Tiptap/ProseMirror
packages as peers/externals, must not import @tiptap/starter-kit at runtime,
and must publish their CSS separately. Install trusted plugins only: they run
with the host page's full JavaScript permissions. Declarative Web Component
attributes and the hosted CDN/UMD build do not load arbitrary plugin packages.
See the public Plugin Development guide for a minimal plugin definition and registration example, browser-side static rendering, document compatibility, packaging, and security guidance.
Tailwind and DaisyUI
The package ships compiled CSS at @alggtta/editor/styles.css. DaisyUI is internally prefixed with ue- to reduce conflicts with consuming apps. You can use the editor in apps with or without Tailwind/DaisyUI.
Migration from v2
onUpdate
// v2
<UniversalEditor onUpdate={(editor) => save(editor.getJSON())} />
// v3
<AlggttaEditor onUpdate={({ json }) => save(json)} />UniversalEditor
AlggttaEditor is the recommended component (since v3). The previous UniversalEditor remains available from the legacy entry during migration:
import { UniversalEditor } from '@alggtta/editor/legacy'Optional Features
Database, Mermaid, AI, export helpers, GuideFlow blocks, and schedule blocks are no longer part of the default core entry. Import the matching subpath and pass its extensions/commands explicitly.
License
Proprietary — Copyright © 2026 Alggtta. All rights reserved. Use is governed by the Alggtta Commercial License Agreement (EULA) and a valid, domain-bound license token issued by Alggtta. See LICENSE.
Versions up to and including 5.1.1 were published under the MIT License and those already-distributed copies remain MIT; this proprietary license applies to 6.0.0 and later.
