@siciyuan404/llm2ui-renderer
v0.1.2
Published
LLM2UI JSON Renderer SDK - Render UI from JSON schemas with a simple API, similar to amis low-code framework
Maintainers
Readme
@llm2ui/renderer
JSON Renderer SDK for LLM2UI - Render UI from JSON schemas with a simple API, similar to amis low-code framework.
Features
- 🚀 Simple API:
render(schema, container)- just like amis - 🎨 Multi-platform: Support for PC Web, Mobile Web, Mobile Native, PC Desktop
- ⚛️ React Integration:
<LLM2UI />component for declarative usage - 💚 Vue Integration: Vue 3 component and composable support
- 🔌 Custom Components: Register your own components easily
- 📦 Tree-shakable: Only bundle what you use
- 📝 TypeScript: Full type definitions included
Installation
npm install @llm2ui/renderer
# or
yarn add @llm2ui/renderer
# or
pnpm add @llm2ui/rendererStyling Setup
The renderer comes with pre-compiled CSS that includes all necessary Tailwind utilities. Just import the styles file:
// In your main entry file (e.g., main.tsx or App.tsx)
import '@siciyuan404/llm2ui-renderer/styles.css';That's it! The styles.css file includes:
- All Tailwind CSS utilities used by the components
- CSS variables for theming (light/dark mode)
- Base styles and resets
Advanced: Custom Tailwind Setup
If you want to customize the theme or use your own Tailwind configuration:
// tailwind.config.js
const llm2uiConfig = require('@siciyuan404/llm2ui-renderer/tailwind.config');
module.exports = {
presets: [llm2uiConfig],
content: [
'./src/**/*.{js,ts,jsx,tsx}',
// Include renderer's dist files for Tailwind to scan
'./node_modules/@siciyuan404/llm2ui-renderer/dist/**/*.{js,cjs}',
],
// Add your customizations here
theme: {
extend: {
// Custom colors, etc.
}
}
};Quick Start
Basic Rendering
import { render } from '@llm2ui/renderer';
const schema = {
version: '1.0',
root: {
id: 'root',
type: 'Container',
children: [
{
id: 'btn',
type: 'Button',
props: { children: 'Click me' }
}
]
}
};
const renderer = render(schema, document.getElementById('app'));With Options
import { createRenderer } from '@llm2ui/renderer';
const renderer = createRenderer({
theme: 'dark',
onEvent: (action, event, componentId) => {
console.log('Event:', action.type, componentId);
}
});
renderer.render(schema, container);
renderer.on('click', (event) => console.log('Clicked:', event.componentId));React Component
import { LLM2UI, type LLM2UIEvent } from '@llm2ui/renderer';
function App() {
const handleEvent = (event: LLM2UIEvent) => {
console.log('Event:', event.type, event.componentId);
};
return (
<LLM2UI
schema={schema}
data={{ user: { name: 'John' } }}
onEvent={handleEvent}
theme="light"
/>
);
}Vue Component
<template>
<LLM2UI
:schema="schema"
:data="{ user: { name: 'John' } }"
@event="handleEvent"
theme="light"
/>
</template>
<script setup lang="ts">
import { LLM2UIVue as LLM2UI, type LLM2UIVueEvent } from '@llm2ui/renderer';
const schema = { /* ... */ };
function handleEvent(event: LLM2UIVueEvent) {
console.log('Event:', event.type, event.componentId);
}
</script>Custom Components
Simple Registration
import { createRenderer } from '@llm2ui/renderer';
const renderer = createRenderer({
customComponents: {
MyButton: ({ children, ...props }) => (
<button className="my-btn" {...props}>{children}</button>
)
}
});With Full Metadata
import { registerCustomComponent } from '@llm2ui/renderer';
registerCustomComponent({
name: 'MyButton',
component: MyButtonComponent,
description: 'A custom button with variants',
category: 'input',
propsSchema: {
variant: { type: 'string', enum: ['primary', 'secondary', 'danger'] },
disabled: { type: 'boolean', default: false },
size: { type: 'string', enum: ['sm', 'md', 'lg'], default: 'md' }
},
tags: ['button', 'action', 'interactive']
});API Reference
render(schema, container, options?)
Renders a UISchema to a DOM container.
schema: UISchema - The schema to rendercontainer: HTMLElement - Target DOM elementoptions: RendererOptions - Optional configuration- Returns:
LLM2UIRendererinstance
createRenderer(options?)
Creates a new renderer instance.
options: RendererOptions - Configuration options- Returns:
LLM2UIRendererinstance
LLM2UIRenderer
Main renderer class with lifecycle methods:
| Method | Description |
|--------|-------------|
| render(schema, container) | Render schema to container |
| update(schema) | Update with new schema |
| destroy() | Clean up and unmount |
| on(event, handler) | Add event listener |
| off(event, handler?) | Remove event listener |
| registerComponent(definition) | Register a custom component |
| getSchema() | Get current schema |
| isMounted() | Check if mounted |
LLM2UI (React Component)
<LLM2UI
schema={schema}
data={{ user: { name: 'John' } }}
onEvent={(event) => console.log(event.type)}
theme="dark"
customComponents={{ MyButton }}
showErrors={true}
/>| Prop | Type | Description |
|------|------|-------------|
| schema | UISchema | The schema to render (required) |
| data | DataContext | Additional data context |
| onEvent | LLM2UIEventCallback | Event handler callback |
| platform | PlatformType | Target platform |
| theme | 'light' \| 'dark' | Theme mode |
| customComponents | Record<string, ComponentType> | Custom components |
| showErrors | boolean | Show error boundaries |
UISchema Format
interface UISchema {
version: string;
root: UIComponent;
data?: DataContext;
theme?: ThemeConfig;
}
interface UIComponent {
id: string;
type: string;
props?: Record<string, unknown>;
children?: UIComponent[];
events?: EventBinding[];
style?: StyleProps;
conditional?: ConditionalConfig;
}Built-in Components
The SDK includes a comprehensive set of UI components:
- Input: Button, Input, Checkbox, Radio, Select, Switch, Slider
- Layout: Container, Grid, Flex, Card, Accordion, Tabs
- Display: Text, Image, Avatar, Badge, Table
- Feedback: Alert, Toast, Dialog, Tooltip
- Navigation: Menu, Breadcrumb, Pagination
Tree-shaking
This package is fully tree-shakable. Only the components and utilities you actually use will be included in your final bundle.
How it works
- ES Modules: The package exports ES modules that bundlers can statically analyze
- Side-effect free: All modules are marked as side-effect free (except CSS)
- Preserved module structure: Each module is kept separate for granular imports
- Named exports: All exports are named, allowing bundlers to eliminate unused code
Best practices for optimal tree-shaking
// ✅ Good - Import only what you need
import { render, LLM2UI } from '@llm2ui/renderer';
import { LLM2UI } from '@llm2ui/renderer/react';
// ❌ Avoid - Importing everything
import * as LLM2UIRenderer from '@llm2ui/renderer';Bundle size optimization
For the smallest possible bundle:
- Use specific entry points (
@llm2ui/renderer/reactor@llm2ui/renderer/vue) - Only import the components you need
- Use a modern bundler (Vite, Webpack 5+, Rollup, esbuild)
- Enable production mode for dead code elimination
License
MIT © LLM2UI Team
