English | 简体中文

TokUI是全球首个 For AI & 零依赖的流式 UI 描述与渲染框架。后端用极简 DSL 描述组件,经 SSE 或 WebSocket 流式推送,前端增量解析、首个 Token 即开始渲染 —— 让 AI 使用极少的 Token 去输出更灵活、更具表现力的 UI。

官网文档站 · 组件画廊演示 · DSL 完整参考 · 在线体验(StackBlitz)


目录


特性

  • 零运行时依赖 —— 前后端均为原生 API,不引入任何运行时 npm 包;产物自包含,gzip 后 ~86KB(ESM)。
  • 流式优先 —— 状态机增量解析,边收边渲染,首个字符到达即开始绘制 DOM。
  • 简洁 DSL —— [card tt:标题][p 内容][/card] 一行描述一个组件,AI 易生成、人易读。
  • 框架无关 —— 原生 JS 可用,另提供 React / Vue / Svelte / Web Component 官方适配器。
  • 插件化组件 —— renderer.register(type, fn) 注册,开箱即用 30+ 组件(卡片、表格、表单、图表、Markdown、代码高亮等)。
  • 事件安全 —— 事件处理器为命名引用(clk:/sub:),需预先 registerHandler 注册,禁止注入可执行代码。
  • 主题驱动 —— CSS 变量 + data-tokui-theme 切换,内置 HSB 算法的 10 级色阶生成器。
  • SSR 友好 —— import 不依赖 window/document,可在 Next.js / Nuxt / SvelteKit 等服务端导入(渲染在客户端进行)。
  • 容错降级 —— 未注册组件渲染为 div.tokui-unknown,渲染抛错生成 details.tokui-error,单点错��不炸整页。
  • 资源防护 —— maxBuffer(1MB)与 maxDepth(100)防止恶意/超长输入耗尽资源。

安装

# npm
npm install @jboltai/tokui

# pnpm
pnpm add @jboltai/tokui

# yarn
yarn add @jboltai/tokui

CDN(零构建)

<link rel="stylesheet" href="https://unpkg.com/@jboltai/tokui/dist/tokui.css">
<script src="https://unpkg.com/@jboltai/tokui/dist/tokui.umd.js"></script>
<!-- 挂载到 window.TokUI 命名空间 -->

jsdelivr 同样可用:把 unpkg.com 换成 cdn.jsdelivr.net/npm


快速开始

引入样式(npm 项目)

import '@jboltai/tokui/css';   // 必须显式引入一次(库样式合一)

三种渲染方式

1. 一次性渲染

import { TokUI } from '@jboltai/tokui';

const tokui = new TokUI({ container: '#app' });
tokui.render('[h1 Hello TokUI][p 这是一段文本]');

2. 流式渲染(feed() 逐步输入)

const tokui = new TokUI({ container: '#app' });
tokui.startStream();
tokui.feed('[card tt:');
tokui.feed('流式卡片]');
tokui.feed('[p 内容边到边渲染]');
tokui.feed('[/card]');
tokui.endStream();   // 刷出缓冲区

3. SSE 连接(服务端推流)

const tokui = new TokUI({
  container: '#chat',
  onEvent: (type, data) => {
    if (type === 'streamEnd') console.log('流结束');
  }
});
tokui.connect('/api/chat', { prompt: '画一个登录卡片' });

SSE 协议约定:data: 行内为 JSON,取 tokui 字段喂给解析器;[DONE] 标记流结束。

Node.js(服务端 Builder)

import { TokUIBuilder } from '@jboltai/tokui/builder';

const b = new TokUIBuilder();
b.card({ tt: '标题' }).h2('内容').p('描述').end();
console.log(b.toString());  // [card tt:标题][h2 内容][p 描述][/card]

Builder 是纯逻辑模块,可在任意 Node 运行时(含 Edge / Serverless)使用,无需 DOM。


在框架中使用

TokUI 提供官方框架适配器,让你用熟悉的声明式 API 渲染 DSL。适配器均 peer-depend 对应框架(不重复打包),并随 @jboltai/tokui 自动引入样式。

适用 入口
@jboltai/tokui-react React 16.8+ <TokUIView dsl={...} /> + useTokUIStream()
@jboltai/tokui-vue Vue 3 <TokUIView :dsl="..." /> + useTokUIStream()
@jboltai/tokui-svelte Svelte 3.46+ use:tokui={{ dsl }} action + <TokUI />
@jboltai/tokui-webc 任意框架 / 无框架 <tokui-view dsl="..."></tokui-view> 自定义元素

React

import { TokUIView } from '@jboltai/tokui-react';

export function App() {
  return <TokUIView dsl="[card tt:你好][p 流式 UI][/card]" theme="default" />;
}

Vue 3

<script setup>
import { TokUIView } from '@jboltai/tokui-vue';
const dsl = '[card tt:你好][p 流式 UI][/card]';
</script>
<template><TokUIView :dsl="dsl" /></template>

Svelte

<script>
  import { tokui } from '@jboltai/tokui-svelte';
</script>
<div use:tokui={{ dsl: '[card tt:你好][p 流式 UI][/card]' }}></div>

Web Component(框架无关)

import defineTokuiElement from '@jboltai/tokui-webc';
defineTokuiElement(); // 注册 <tokui-view>
<tokui-view dsl="[card tt:你好][p 流式 UI][/card]"></tokui-view>

各适配器的流式 / SSE 用法见对应包 README。


架构

三层数据流

后端 TokUIBuilder 生成 DSL  →  SSE 推送  →  前端 TokUIParser 增量解析  →  TokUIRenderer 渲染 DOM

核心模块

模块 职责
core/parser.js 基于状态机(TEXT / TAG_OPEN / TAG_CLOSE)的流式解析器,支持 feed() 增量与 parse() 一次性
core/renderer.js 组件渲染引擎,slotStack 管理嵌套容器插槽,VARIANTS 白名单校验变体,深度上限 50
core/event-bus.js 事件总线单例,registerHandler(name, fn) 注册,DSL 用 clk:/sub: 绑定
core/theme.js CSS 变量驱动主题管理,data-tokui-theme 切换
core/color-generator.js 基于 HSB 算法的 10 级色板与主题 token 生成器
components/* 按类型分文件的组件库,index.js 统一注册
server/tokui-builder.js 链式 API 生成 DSL,支持 toString()toChunks() 两种输出
server/sse-server.js Node.js 原生 http 实现的 SSE 演示服务器

DSL 语法速查

[组件类型 属性:值 内容文本]           ; 自闭合
[card tt:标题][p 内容][/card]         ; 容器嵌套
ph:"含空格的值"                       ; 值含空格用双引号
v:"primary,sm"                        ; 多变体逗号分隔
stripe                                ; 布尔属性(只写 key)

常用属性简写

简写 含义 简写 含义
tt title tx text
l label ph placeholder
u url s src / source
n name v value / variant
act action mtd method
clk onclick 处理器名 sub onsubmit 处理器名
dis disabled ro readonly
req required chk checked
id 元素 ID(也作 upd 更新目标) w/h/bg/fc 宽/高/背景/字色

布尔属性(只写 key)

stripe dis ro req chk multi auto plain round closable bordered open pill dot leaf inline rounded container

完整列表以 parser.jsBOOLEAN_ATTRS Set 为准。

变体系统

DSL 写 v:primary,渲染器生成 CSS 类 tokui-btn--primary。变体名经 VARIANTS 白名单校验,未知变体静默丢弃。

动态更新

[upd id:目标ID v/act/tt/tx:新值]    ; 更新已渲染组件的值/动作/标题/文本

完整参考

详细属性表与容器类型清单见 demo/TOKUI_DSL_REFERENCE.md


组件清单

按文件分组,开箱即用:

文件 组件
basic.js 标题 h1–h6、段落、链接、Markdown、代码块、代码高亮、徽标、按钮、提示、分隔线等
table.js 表格(table / thead / tbody / tr / desc
form.js 表单、输入框、文本域、下拉、单选/复选、开关、日期选择器、标签输入等
layout.js 卡片、栅格行/列、列表、图片集、描述列表等
chart.js 纯 SVG 零依赖图表:bar / line / pie / radar / donut / scatter / gantt / funnel
lightbox.js 图片灯箱预览

容器类型(需 [/type] 闭合,完整列表见 parser.jsCONTAINERS Set):

form table thead tbody card ft row col list select radio code imgs md textarea
tabs tab accordion collapse dialog btngroup picker timeline steps drawer ol ul i
item think bubble toolbar badge-box dropdown transfer cascader tree tn step desc
carousel popover input-tag watermark menu

Builder API(服务端)

TokUIBuilder 提供链式调用生成 DSL,两种输出方式:

const b = new TokUIBuilder();

// toString() —— 一次性输出完整字符串
b.card({ tt: '卡片' }).p('内容').end();
const dsl = b.toString();

// toChunks() —— 分块数组,配合 SSE 逐块推送
const chunks = b.reset().card({ tt: '卡片' }).p('内容').end().toChunks();

自动闭合toString() / toChunks() 内部调用 _finalizeChunks(),未关闭容器会自动补全,无需手动 endAll()

双行为方法thead()inputTag()quickReply()agent() 根据参数自动选择自闭合或容器模式。

命名避让:布局用 row_layout() / col_layout() 以避让表格的 row()


主题系统

通过 CSS 变量 + data-tokui-theme 属性切换:

import { setTheme } from '@jboltai/tokui';
setTheme('dark');   // 切换为暗色主题

自定义主题色可用色阶生成器:

import { generatePalette, generateThemeTokens } from '@jboltai/tokui';
const tokens = generateThemeTokens({ primary: '#1677ff', danger: '#ff4d4f' });
// 输出 { '--tokui-primary-1' ... '--tokui-primary-10' } 共 10 级 CSS 变量映射

扩展组件

新增一个组件需四步:

  1. 注册渲染函数src/components/*.js):

    renderer.register('mycard', (node, rc, parentType) => {
      const el = renderer.el('div', { class: 'tokui-mycard' });
      el.textContent = node.attrs.tt || '';
      rc(node.children, el);   // 递归渲染子节点
      return el;
    });
    
  2. 若为容器类型,加入 src/core/parser.jsCONTAINERS Set。若内容含 [ 不应被解析(如代码),同时加入 _isRawContent() 类型列表。

  3. 添加 Builder 方法src/server/tokui-builder.js):自闭合用 _selfClosing(),容器用 _open() / end()

  4. 添加样式src/styles/tokui.css):类名 .tokui-mycard,变体用 .tokui-mycard--{variant} 并加入 renderer.jsVARIANTS 白名单。

最后在 tests/ 补测试(见下)。


测试

基于 Node.js 内置 assert 的自定义 runner,零测试框架依赖:

npm test            # 全量 24 个测试文件,866+ 用例
npm run test:parser # 仅解析器
npm run test:builder
npm run test:core   # event-bus + theme + renderer
npm run typecheck   # tsc 类型检查(含反向 @ts-expect-error 断言)
npm run coverage    # c8 覆盖率(核心模块 ~91%)

node tests/test-xxx.js          # 跑单个���试文件

renderer 测试依赖 tests/helpers/dom-mock.js 提供的最小化 DOM mock。断言失败进程退出码为 1。


项目结构

.
├── src/
│   ├── core/              # 解析器、渲染器、事件总线、主题、色阶生成器
│   ├── components/        # 组件库(basic/table/form/layout/chart/lightbox)
│   ├── server/            # Builder 链式 API + SSE 演示服务器
│   ├── styles/            # tokui.css + themes/(default, dark)
│   └── index.js           # 主入口,整合 TokUI 类
├── packages/              # 框架适配器 monorepo(pnpm workspace)
│   ├── react/             # @jboltai/tokui-react
│   ├── vue/               # @jboltai/tokui-vue
│   ├── svelte/            # @jboltai/tokui-svelte
│   ├── webc/              # @jboltai/tokui-webc(Web Component)
├── demo/                  # 组件画廊演示
├── tests/                 # 自定义 runner 测试套件(24 文件 / 866+ 用例)
├── docs/                  # VitePress 文档站
└── package.json

路线图

TokUI 正在向多语言后端 SDK 与多样式库前端主题演进。

图例:✅ 已支持 · 🚧 规划中

后端 SDK 多语言支持

语言 / 运行时 状态 说明
Node.js TokUIBuilder 链式 API + SSE 演示服务器(当前唯一实现)
Python 🚧 规划中
Rust 🚧 规划中
Java 🚧 规划中
Go 🚧 规划中
跨语言 DSL 规范固化 🚧 共享解析契约,保证各 SDK 输出一致

前端集成

能力 状态 说明
React / Vue / Svelte / Web Component 适配器 @jboltai/tokui-{react,vue,svelte,webc}
CSS 变量主题(default / dark data-tokui-theme 切换
HSB 色板生成器 任意主色生成 10 级色阶
TailwindCSS 适配 🚧 原子类映射 / 主题 token 桥接
UnoCSS 适配 🚧 规划中
主题市场 / 主题分享 🚧 社区可分享主题包