Quick Reference: Understanding the relationship between ObjectUI Renderer and Shadcn UI components
- 📦 Pure UI Component Library
- 🎨 Built on Radix UI + Tailwind CSS
- 💻 Requires writing React code
- 🔧 Controlled via Props
- 🔄 Schema Interpreter
- 📋 JSON configuration-driven
- 🚀 Zero-code usage
- 🔗 Automatic data binding and validation
| Shadcn UI | ObjectUI Renderer | Enhanced Features |
|---|---|---|
<Input /> |
{ type: "input" } |
✅ Expressions, ✅ Validation, ✅ Data Binding |
<Button /> |
{ type: "button" } |
✅ Action Mapping, ✅ Loading States |
<Select /> |
{ type: "select" } |
✅ Dynamic Options, ✅ Remote Search |
<Dialog /> |
{ type: "dialog" } |
✅ Conditional Display, ✅ Form Integration |
<Table /> |
{ type: "table" } |
✅ Basic Table Rendering |
<Card /> |
{ type: "card" } |
✅ Dynamic Content, ✅ Action Buttons |
<Form /> |
{ type: "form" } |
✅ Validation Engine, ✅ Submit Handling |
<Tabs /> |
{ type: "tabs" } |
✅ Dynamic Tabs, ✅ Lazy Loading |
<Badge /> |
{ type: "badge" } |
✅ Status Mapping, ✅ Color Rules |
<Alert /> |
{ type: "alert" } |
✅ Conditional Display, ✅ Auto-dismiss |
These components have no direct Shadcn counterparts and are advanced business components unique to ObjectUI:
| Component | Type | Purpose |
|---|---|---|
| data-table | Complex Component | Advanced table with sorting/filtering/pagination |
| timeline | Complex Component | Timeline/Gantt chart |
| filter-builder | Complex Component | Visual query builder |
| chatbot | Complex Component | Chatbot interface |
| tree-view | Data Display | Tree structure |
| statistic | Data Display | Statistical metric cards |
import { Input } from '@/ui/input';
import { Button } from '@/ui/button';
function LoginForm() {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const handleSubmit = async (e) => {
e.preventDefault();
await fetch('/api/login', {
method: 'POST',
body: JSON.stringify({ email, password })
});
};
return (
<form onSubmit={handleSubmit}>
<Input
value={email}
onChange={e => setEmail(e.target.value)}
placeholder="Email"
/>
<Input
type="password"
value={password}
onChange={e => setPassword(e.target.value)}
placeholder="Password"
/>
<Button type="submit">Login</Button>
</form>
);
}{
"type": "form",
"api": "/api/login",
"fields": [
{
"name": "email",
"type": "input",
"inputType": "email",
"placeholder": "Email",
"required": true
},
{
"name": "password",
"type": "input",
"inputType": "password",
"placeholder": "Password",
"required": true
}
],
"actions": [
{
"type": "button",
"label": "Login",
"actionType": "submit"
}
]
}import { Table } from '@/ui/table';
function UserTable() {
const [users, setUsers] = useState([]);
const [page, setPage] = useState(1);
const [sort, setSort] = useState('name');
useEffect(() => {
fetchUsers(page, sort).then(setUsers);
}, [page, sort]);
return (
<div>
<Table>
<TableHeader>
<TableRow>
<TableHead onClick={() => setSort('name')}>Name</TableHead>
<TableHead onClick={() => setSort('email')}>Email</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{users.map(user => (
<TableRow key={user.id}>
<TableCell>{user.name}</TableCell>
<TableCell>{user.email}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
<Pagination page={page} onChange={setPage} />
</div>
);
}{
"type": "data-table",
"api": "/api/users",
"columns": [
{
"name": "name",
"label": "Name",
"sortable": true
},
{
"name": "email",
"label": "Email",
"sortable": true
}
],
"pagination": {
"pageSize": 20
}
}✅ Highly customized interaction logic required
✅ Complex component behavior difficult to express in Schema
✅ Performance-critical optimization (avoid Schema parsing overhead)
✅ Existing large React component codebase
✅ Rapidly build data management interfaces
✅ Configuration-driven, easy to maintain
✅ Dynamic UI required (fetch configuration from server)
✅ Low-code/No-code platforms
✅ AI-generated UI
ObjectUI supports embedding custom React components within Schema:
{
"type": "page",
"body": [
{
"type": "card",
"title": "User Statistics",
"body": {
"type": "custom",
"component": "CustomChart",
"props": {
"data": "${chartData}"
}
}
},
{
"type": "data-table",
"api": "/api/users"
}
]
}// Register custom component
import { registerRenderer } from '@object-ui/react';
import CustomChart from './CustomChart';
registerRenderer('custom', ({ schema }) => {
const Component = schema.component; // "CustomChart"
return <CustomChart {...schema.props} />;
});A: Compared to using Shadcn directly, there is a slight overhead (<10%), but with virtualization and caching optimizations, the difference is negligible in real-world applications.
A: Yes! You can override styles by passing Tailwind class names via the className property.
A: Use registerRenderer to register custom renderers, or use type: "custom" to embed React components.
A: Full support! All Schemas have complete TypeScript type definitions.
Last Updated: 2026-01-23