Framework-agnostic rendering engine for server-driven UI
Build dynamic forms and UIs from JSON schemas with full support for React, Vue, and Vanilla JavaScript. Schepta provides a powerful, type-safe foundation for creating flexible, schema-driven applications.
- π¨ Framework Agnostic Core: Single source of truth that works across React, Vue, and Vanilla JS
- π Schema-Driven Forms: Define complex forms using JSON schemas with validation
- π Pluggable Integrations: Built-in support for react-hook-form, Formik, and native form management
- π― Dynamic Component Registry: Register and resolve components at runtime
- π Middleware System: Transform schemas and add business logic with composable middlewares
- π§© Custom Components: Easily integrate your own components with full framework support
- β‘ Reactive System: Handle both declarative and imperative state management
- π Conditional Logic: Show/hide fields based on form values using template expressions
- π‘οΈ Type Safe: Full TypeScript support with strict type checking
- π§ͺ Well Tested: Comprehensive E2E test suite with Playwright
Schepta follows a three-layer architecture:
βββββββββββββββββββββββββββββββββββββββ
β Your Application β
β (React, Vue, Vanilla JS) β
βββββββββββββββββββ¬ββββββββββββββββββββ
β
βββββββββββββββββββΌββββββββββββββββββββ
β Factories Layer β
β Framework-specific form factories β
β β’ @schepta/factory-react β
β β’ @schepta/factory-vue β
β β’ @schepta/factory-vanilla β
βββββββββββββββββββ¬ββββββββββββββββββββ
β
βββββββββββββββββββΌββββββββββββββββββββ
β Adapters Layer β
β Framework-specific runtime logic β
β β’ @schepta/adapter-react β
β β’ @schepta/adapter-vue β
β β’ @schepta/adapter-vanilla β
βββββββββββββββββββ¬ββββββββββββββββββββ
β
βββββββββββββββββββΌββββββββββββββββββββ
β Core Layer β
β Framework-agnostic engine β
β β’ @schepta/core β
β β’ Component orchestration β
β β’ Middleware system β
β β’ Schema validation β
βββββββββββββββββββββββββββββββββββββββ
# Using pnpm (recommended)
pnpm install
# Build all packages
pnpm buildimport { FormFactory } from '@schepta/factory-react';
import type { FormSchema } from '@schepta/core';
const schema: FormSchema = {
type: 'object',
properties: {
firstName: {
type: 'string',
'x-component': 'InputText',
'x-component-props': {
label: 'First Name',
placeholder: 'Enter your first name'
}
}
}
};
function MyForm() {
const handleSubmit = (values: any) => {
console.log('Form submitted:', values);
};
return (
<FormFactory
schema={schema}
onSubmit={handleSubmit}
/>
);
}<script setup lang="ts">
import { FormFactory } from '@schepta/factory-vue';
import type { FormSchema } from '@schepta/core';
const schema: FormSchema = {
type: 'object',
properties: {
firstName: {
type: 'string',
'x-component': 'InputText',
'x-component-props': {
label: 'First Name',
placeholder: 'Enter your first name'
}
}
}
};
const handleSubmit = (values: any) => {
console.log('Form submitted:', values);
};
</script>
<template>
<FormFactory
:schema="schema"
:on-submit="handleSubmit"
/>
</template>import { createFormFactory } from '@schepta/factory-vanilla';
import type { FormSchema } from '@schepta/core';
const schema: FormSchema = {
type: 'object',
properties: {
firstName: {
type: 'string',
'x-component': 'InputText',
'x-component-props': {
label: 'First Name',
placeholder: 'Enter your first name'
}
}
}
};
const container = document.getElementById('form-container');
const factory = createFormFactory({
schema,
container,
onSubmit: (values) => {
console.log('Form submitted:', values);
}
});Define your forms using JSON schemas with custom extensions:
x-component: Specify which component to renderx-component-props: Pass props to the componentx-ui: UI-specific configuration (order, visibility, etc.)x-content: Static content for non-input components
Extend Schepta with your own components:
// React
const customComponents = {
MyCustomInput: createComponentSpec({
id: 'MyCustomInput',
type: 'field',
component: () => MyCustomInputComponent
})
};
<FormFactory
schema={schema}
customComponents={customComponents}
/>Transform schemas and add business logic:
const myMiddleware: MiddlewareFn = (node, context) => {
// Transform node based on context
if (context.formValues.userType === 'admin') {
node.props.disabled = false;
}
return node;
};
<FormFactory
schema={schema}
middlewares={[myMiddleware]}
/>Use JEXL expressions for conditional logic:
{
"properties": {
"showField": {
"x-ui": {
"visible": "{{formValues.userType == 'admin'}}"
}
}
}
}- @schepta/core: Framework-agnostic rendering engine
- Component orchestration
- Middleware system
- Schema validation (AJV)
- Template expressions (JEXL)
Framework-specific runtime implementations:
- @schepta/adapter-react: React runtime with hooks
- @schepta/adapter-vue: Vue runtime with Composition API
- @schepta/adapter-vanilla: Vanilla JS runtime with EventEmitter
Complete form solutions:
- @schepta/factory-react: React form factory with default components
- @schepta/factory-vue: Vue form factory with default components
- @schepta/factory-vanilla: Vanilla JS form factory with default components
Visit schepta.org to see Schepta in action with live, interactive examples:
- React Basic: Native Schepta forms with custom components
- React + Material UI: Integration with MUI components
- React + Chakra UI: Integration with Chakra UI
- React Hook Form: Integration with react-hook-form
- Formik: Integration with Formik
- Vue Basic: Native Schepta forms with custom components
- Vue + Vuetify: Integration with Vuetify
- Vanilla JS: Pure JavaScript implementation
Comprehensive E2E test suite using Playwright:
# Run all E2E tests (26 tests)
pnpm test:e2e
# Run specific framework tests
npx playwright test tests/e2e/react.spec.ts
npx playwright test tests/e2e/vue.spec.ts
npx playwright test tests/e2e/vanilla.spec.ts
# Run with UI mode
pnpm test:e2e:ui
# Run unit tests
pnpm test- β React: 11 E2E tests (including RHF and Formik integrations)
- β Vue: 8 E2E tests
- β Vanilla: 7 E2E tests
Full documentation is available at schepta.org
Documentation includes:
- π Getting Started guides
- π§ API reference
- ποΈ Architecture overview
- π Integration guides
- π Examples and recipes
- π― Best practices
# Install dependencies
pnpm install
# Build all packages
pnpm build
# Run type checking
pnpm type-check
# Run linting
pnpm lint# Watch mode for a specific package
cd packages/core && pnpm dev
cd packages/adapters/react && pnpm dev
cd packages/factories/react && pnpm dev
# Clean build artifacts
pnpm cleanFor detailed contribution guidelines, visit the documentation.
schepta/
βββ packages/
β βββ core/ # Framework-agnostic core
β βββ adapters/
β β βββ react/ # React adapter
β β βββ vue/ # Vue adapter
β β βββ vanilla/ # Vanilla JS adapter
β βββ factories/
β βββ react/ # React form factory
β βββ vue/ # Vue form factory
β βββ vanilla/ # Vanilla JS form factory
βββ tests/ # E2E tests with Playwright
β βββ e2e/ # Test specs
β βββ playwright.config.ts # Playwright configuration
βββ instances/ # Shared schema instances
β βββ form/ # Form schemas
βββ docs/ # Documentation site (VitePress)
β βββ .vitepress/
β β βββ showcases/ # Interactive showcases (React, Vue, Vanilla)
β β βββ react/ # React examples (basic, MUI, Chakra, RHF, Formik)
β β βββ vue/ # Vue examples (basic, Vuetify)
β β βββ vanilla/ # Vanilla JS examples
β βββ en-US/showcases/ # Showcase pages (English)
β βββ pt-BR/showcases/ # Showcase pages (Portuguese)
β βββ es-ES/showcases/ # Showcase pages (Spanish)
βββ scripts/ # Build and publish scripts
import { FormFactory } from '@schepta/factory-react';
import { useForm } from 'react-hook-form';
function RHFForm() {
const methods = useForm();
return (
<FormFactory
schema={schema}
renderers={{
field: createRHFFieldRenderer(methods)
}}
onSubmit={methods.handleSubmit(onSubmit)}
/>
);
}import { FormFactory } from '@schepta/factory-react';
import { TextField, Select } from '@mui/material';
const muiComponents = {
InputText: createComponentSpec({
id: 'InputText',
type: 'field',
component: () => ({ label, ...props }) => (
<TextField label={label} {...props} />
)
})
};
<FormFactory
schema={schema}
components={muiComponents}
/>Contributions are welcome! Please read our contributing guidelines before submitting PRs.
Schepta Non-Commercial License (SNCL)
Schepta is free to use for:
- β Personal projects
- β Educational purposes
- β Research and academic projects
- β Non-profit organizations
- β Open-source projects
Commercial use requires a separate license.
For commercial licensing inquiries, please contact us at: https://github.com/guynikan/schepta
See LICENSE for full terms.
Built with β€οΈ using TypeScript, Turbo, and PNPM