@ecsplico/editor

中文文档
4.3.2发布于 2026/10/25MITTypeScriptES Module近 30 天下载 2062

Vue and React editor library on TipTap v3 (Vue: Nuxt UI; React: shadcn/ui): framework-free features with Vue and React bindings, simple and advanced presets, tree-shakeable entries. Built ESM with type declarations.

此软件包已被标记为弃用

renamed to @skaile/forge-editor

原始使用文档
文档目录5 节
  1. Prerequisites
  2. Install
  3. Nuxt quick start
  4. Building and developing in this repository
  5. Documentation

@ecsplico/editor

A Vue and React editor library on TipTap v3. Editors are assembled from features: the simple editor is the core features alone (formatting, headings, lists, quotes, code, undo/redo) and needs no backend, no Yjs and no feature code; the advanced editor composes every feature (media, mentions, transcripts, composites, authors, comments, AI, collaboration, block UI, site-wide Obsidian themes and their integrations) on both surfaces. The framework-free ./core holds the feature model, and every feature's logic is framework-free too (./<feature>): a feature is built from a typed UI binding (<x>FeatureCore(ui)) that the Vue layer (./<feature>/vue, Nuxt UI chrome) and the React layer (./<feature>/react, shadcn/ui on Radix and Tailwind) fill with their components, node views and notice seam. Toolbar, settings panel and modal, outline, AI sidebar, comments margin, composite table and inspector, and the file browser are components you place anywhere beside an editor; both layers ship the simple editor (./vue/simple, ./react/simple) and the advanced editor (./vue/advanced, ./react/advanced).

Prerequisites

  • Node ≥ 22 and Bun (the repository is a Bun workspace: packages/*, examples/*).
  • A Vite- or Nuxt-based app (@vitejs/plugin-vue / @vitejs/plugin-react, or Nuxt). The published package is a built ESM package: every exports subpath resolves to dist/**/*.js with .d.ts (Vue SFCs are compiled, React .tsx is compiled to JSX-runtime JS), the CSS sheets are copied, and the source maps embed the sources (src itself is not published). Output is one module per source file, so entries stay tree-shakeable.
  • Required peer dependencies (install them in the consuming app so the host and the library share one instance of each): @tiptap/core, @tiptap/pm, yjs, @hocuspocus/provider. Yjs and the provider are required peers because shared prop types in the .d.ts reference them; a simple-editor bundle does not contain their implementation (proven below). Per layer (all optional peers): Vue vue, @nuxt/ui, @tiptap/vue-3; React react, react-dom, @tiptap/react, @iconify/react; code surface (/code) @codemirror/state, @codemirror/view, @codemirror/language, @codemirror/commands, @codemirror/search, @lezer/highlight, plus the @codemirror/lang-* packs you register (the package ships none).
  • Tailwind CSS 4 (tailwindcss) for the Nuxt UI theme (Vue) or the shadcn classes (React), and the icon collection @iconify-json/lucide. React hosts also need tw-animate-css (enter/exit animations of the dialog, dropdown and tooltip).

Install

From npmjs (public, no token and no .npmrc needed):

npm install @ecsplico/editor      # or: bun add @ecsplico/editor / pnpm add @ecsplico/editor

Inside this repository the package is a workspace member, so consumers there declare "@ecsplico/editor": "workspace:*".

Nuxt quick start

Install the peers next to the package (vue, @nuxt/ui, @tiptap/core, @tiptap/pm, @tiptap/vue-3, yjs, @hocuspocus/provider, tailwindcss, @iconify-json/lucide), then register the module after @nuxt/ui:

// nuxt.config.ts
export default defineNuxtConfig({
  ssr: false, // TipTap renders on the client only
  modules: ['@nuxt/ui', '@ecsplico/editor/nuxt'],
  css: ['~/assets/main.css'],
})
/* app/assets/main.css */
@import "tailwindcss";
@import "@nuxt/ui";

Wrap the app in <UApp> (app/app.vue: <UApp><NuxtPage /></UApp>) and mount an editor on a page (the simple editor needs no backend):

<script setup lang="ts">
import { SimpleEditor } from '@ecsplico/editor/vue/simple'
import { ref } from 'vue'
const content = ref()
</script>

<template>
  <SimpleEditor v-model="content" />
</template>

The module's API routes call the host's EditorPorts (identity first, then one port per capability: documents, collabState, directory, assets, settings, themes, models, comments). Register them in a Nitro plugin; without them the client logs „Einstellungen konnten nicht geladen werden“ and every route answers 500. A route whose port you leave out answers 501. These minimal ports keep everything in memory and let any visitor in (replace authenticate and the storage with yours):

// server/plugins/editor-adapter.ts
import type { JSONContent } from '@tiptap/core'
import { type AssetStore, setEditorPorts } from '@ecsplico/editor/server'

export default defineNitroPlugin(() => {
  const contents = new Map<string, JSONContent>()
  const states = new Map<string, Uint8Array>()
  const assets = new Map<string, Parameters<AssetStore['storeAsset']>[1]>()
  setEditorPorts({
    // `null` = 401 on API routes; on /collab the socket is closed with 4401 (HTTP 401 at the upgrade with `collab.authenticateUpgrade`)
    identity: { authenticate: async () => ({ id: 'demo', username: 'demo' }) },
    documents: {
      loadContent: async id => contents.get(id) ?? null,
      storeContent: async (id, content) => { contents.set(id, content) },
      listContents: async () => [...contents].map(([id, content]) => ({ id, content })),
    },
    collabState: {
      loadState: async id => states.get(id) ?? null,
      storeState: async (id, state) => { states.set(id, state) },
      removeState: async (id) => { states.delete(id) },
    },
    directory: { listUsers: async () => [] },
    assets: {
      storeAsset: async (id, asset) => { assets.set(`${id}/${asset.name}`, asset) },
      loadAsset: async (id, name) => {
        const asset = assets.get(`${id}/${name}`)
        if (!asset) return null
        const { data, ...record } = asset
        return { record, data }
      },
    },
  })
})

The advanced editor, every adapter method, collaboration and AI are covered in the Nuxt quick start and the EditorPorts guide.

Building and developing in this repository

bun run build:editor (tsdown, config packages/editor/tsdown.config.ts) writes packages/editor/dist: ESM plus .d.ts for every exports subpath (the entries are read from the skaile-source condition of package.json#exports, so a new export is built as soon as it is declared), unbundled one module per source file, source maps with embedded sources, CSS copied, and the Nuxt runtime directory (dist/nuxt/runtime: plugin, server routes, utils) as separate files next to the module that Nuxt and Nitro compile in the host. Dependencies and peers are never bundled.

Each exports entry carries a custom skaile-source condition first (pointing at src) followed by types/import (or default) pointing into dist. This repository's Nuxt app (nuxt.config.ts) and the examples (examples/*/vite.config.ts, tsconfig.json#customConditions) enable that condition for Vite, Nitro and the type checker, so editing the library needs no build step in dev. Consumers outside the repository never set the condition and get dist. bun run check:editor-entries builds first and judges the built output through exports (no skaile-source), so it proves what is published; bun run check:editor-composition builds first and loads the built entries; bun run typecheck:editor resolves through src (customConditions: ["skaile-source"] in packages/editor/tsconfig.json).

Documentation

The documentation lives at https://skaile-ai.github.io/skaile-editor/** (the package itself no longer ships guides):

  • Getting started: what the package is, installation, quick starts for Nuxt, plain Vue and React, glossary.
  • Tutorial: build one editor step by step, including an own block, the backend, AI and the React surface.
  • Guides: feature composition, Nuxt module, EditorPorts, collaboration, AI, themes, composites, file browser, production, storage adapters, migration.
  • Reference: every public export, presets and features, the feature contract, CSS and UI-provider requirements, dependency rules, commands, changelog.
  • AI agents: how coding agents read these docs, integrate and extend the editor, invariants and verification.

Machine-readable entry points: llms.txt, llms-full.txt, and an installable Agent Skill:

npx skills add https://skaile-ai.github.io/skaile-editor

Runnable examples live in the repository: examples/ and the Nuxt app (bun run dev, port 3056). To work on the documentation site from a checkout of the repository, run bun run docs:dev (development server) or bun run docs:build (static build); see docs/README.md.

版本与发布记录

@ecsplico/editor 共发布 21 个版本,首次发布于 2026/10/11;过去 12 个月发布了 21 个版本。

版本发布日期距今
4.3.2latest2026/10/2520 天前
4.3.12026/10/2421 天前
4.3.02026/10/2421 天前
4.2.02026/10/2322 天前
4.1.02026/10/2322 天前
4.0.02026/10/2123 天前

关于 @ecsplico/editor 的常见问题

@ecsplico/editor 是什么?

Vue and React editor library on TipTap v3 (Vue: Nuxt UI; React: shadcn/ui): framework-free features with Vue and React bindings, simple and advanced presets, tree-shakeable entries. Built ESM with type declarations.注意:该包已被作者标记为弃用——renamed to @skaile/forge-editor

如何安装 @ecsplico/editor?

在项目目录运行 npm install @ecsplico/editor,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:yjs(^13.6.33)、@tiptap/pm(^3.31.3)、@tiptap/core(^3.31.3)、@hocuspocus/provider(^4.7.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@ecsplico/editor 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@ecsplico/editor 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@ecsplico/editor 可以商用吗?

@ecsplico/editor 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@ecsplico/editor 的下载量有多少?

根据 npm 官方下载统计,@ecsplico/editor 在 2026/10/13 – 2026/11/11 这 30 天内被下载 2,062 次,日均约 69 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@ecsplico/editor 还在维护吗?

最新版本 4.3.2 发布于 2026/10/25(20 天前);至今共发布 21 个版本,其中过去 12 个月发布了 21 个;首次发布于 2026/10/11。作者已将其标记为弃用,新项目建议寻找替代方案。