Transform JSON configurations into fully-functional, responsive UI forms in real-time.
An open-source, lightweight web application for frontend developers and internal tools teams to rapidly build, preview, and validate dynamic forms without writing HTML or JSX. Perfect for rapid prototyping, internal CRUD interfaces, and form-driven applications.
- Overview
- Key Features
- How It Works
- Supported Components
- JSON Configuration Guide
- Getting Started
- Usage Examples
- Advanced Usage
- JSON Schema Reference
- Styling & Theming
- Project Structure
- Available Scripts
- Deployment Guide
- Performance Considerations
- Browser Support
- Limitations
- Future Roadmap
- Contributing
- License
JSON UI Builder is a dynamic form generator that converts JSON configurations into production-ready user interfaces. Instead of hand-coding HTML forms or complex React components, you write a simple JSON structure describing your form fields—and the app renders a fully-styled, responsive form in real-time.
- Zero Boilerplate: No JSX, HTML, or CSS needed. Just describe your form in JSON.
- Instant Feedback: Real-time preview as you edit your JSON configuration.
- Built-in Validation: JSON syntax validation with developer-friendly error messages.
- Mobile-First Design: All forms are responsive and mobile-friendly by default.
- Perfect for Teams: Ideal for frontend developers building internal tools and rapid prototypes.
- Open Source: Fully transparent, extensible, and community-driven.
- Rapid Form Prototyping: Build complex forms in minutes, not hours.
- Internal Admin Tools: Generate CRUD interfaces for business applications.
- Dynamic Questionnaires: Create survey and quiz forms on the fly.
- Template-Based Forms: Pre-build form templates for reuse across projects.
- Training & Learning: Understand form architecture without diving into code.
✅ Real-Time JSON Validation
- Instant syntax error detection and user-friendly error messages.
- See validation status (Valid/Invalid) in the UI.
✅ Live Preview
- Side-by-side JSON editor and form preview.
- Changes appear immediately as you edit JSON.
✅ Mobile-Responsive Design
- All forms adapt perfectly to any screen size.
- Touch-friendly inputs and controls.
✅ Performance Optimized
- Lightweight rendering engine.
- Memoized components prevent unnecessary re-renders.
- Minimal bundle size for fast load times.
✅ Grid Layout System
- Split-panel interface (Editor + Preview + Console).
- Responsive breakpoints for optimal viewing on all devices.
✅ Developer Console
- Real-time error tracking and messaging.
- System status indicators.
✅ 9+ UI Components
- Input fields (multiple types)
- Select dropdowns (single & multi-select)
- Radio buttons
- File upload
- Range sliders
- Color pickers
- Checkboxes
- Textareas
- Buttons
┌────────────────────────────────────────────────────┐
│ JSON UI Builder Application │
├────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────┐ ┌──────────────────────┐ │
│ │ JSON Editor │ │ Live Preview │ │
│ │ (contentEditable)| │ (Component Render) │ │
│ │ │ │ │ │
│ │ • Edit JSON │ │ • Field Rendering │ │
│ │ • Real-time │ │ • Instant Update │ │
│ │ updates │ │ • Responsive Layout │ │
│ └──────────────────┘ └──────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────┐ │
│ │ Developer Console │ │
│ │ • JSON Error Messages │ │
│ │ • System Status Indicators │ │
│ └──────────────────────────────────────────────┘ │
│ │
└────────────────────────────────────────────────────┘
⬇️ Flow
JSON Input → Parse & Validate → Extract Fields → Render Components
- User Enters JSON → Paste or edit JSON configuration in the left panel
- Real-Time Parsing → JSON is parsed on every keystroke
- Validation Check → Syntax errors are caught and displayed in the console
- Component Extraction → If valid, extract field definitions from
fieldsarray - Component Mapping → Map each field's
controlTypeto corresponding React component - Render Preview → Display rendered form on the right side
- User Interaction → (Placeholder) Form is ready for user input
| Component | Purpose |
|---|---|
JsonEditor |
contentEditable div for JSON input with real-time validation |
Preview |
Renders form based on parsed JSON |
LayoutCases |
Switch statement maps controlType to React components |
Console |
Displays JSON parsing errors and system status |
Input, Select |
UI component wrappers with TailwindCSS styling |
The application supports 13+ input types organized by control type:
All standard HTML5 input types using the versatile Input component.
Key Properties:
inputType(required) - Specifies the HTML input type- Other common properties:
name,label,placeholder,required,disabled,defaultValue
Supported inputType Values:
| Input Type | Description | Example Use |
|---|---|---|
text |
Standard text input | Names, addresses |
email |
Email validation | Email addresses |
password |
Masked password | Passwords, secrets |
number |
Numeric with spinner | Ages, quantities |
tel |
Telephone format | Phone numbers |
url |
URL validation | Websites, links |
date |
Date picker | Birth dates, deadlines |
time |
Time picker | Appointment times |
datetime-local |
DateTime picker | Meeting schedules |
color |
Color picker | Preferences, themes |
search |
Search-optimized | Search queries |
file |
File upload | Documents, images |
range |
Slider control | Ratings, ranges |
checkbox |
Boolean toggle | Agreements, permissions |
radio |
Radio buttons | Single choice options |
Examples:
Text Input:
{
"controlType": "input",
"inputType": "text",
"name": "fullName",
"label": "Full Name",
"placeholder": "John Doe",
"required": true
}Email Input:
{
"controlType": "input",
"inputType": "email",
"name": "email",
"label": "Email Address",
"placeholder": "user@example.com"
}Radio Button Group:
{
"controlType": "input",
"inputType": "radio",
"name": "gender",
"label": "Gender",
"options": [
{ "label": "Male", "value": "male" },
{ "label": "Female", "value": "female" }
]
}Checkbox:
{
"controlType": "input",
"inputType": "checkbox",
"name": "agreeTerms",
"label": "I agree to Terms"
}Single or multi-select dropdown lists with options.
Key Properties:
options(required) - Array of{label, value}objectsmultiple- Allow multiple selections- Other common properties:
name,label,required,disabled
Example - Single Select:
{
"controlType": "select",
"name": "country",
"label": "Select Country",
"required": true,
"options": [
{ "label": "India", "value": "india" },
{ "label": "USA", "value": "usa" },
{ "label": "Canada", "value": "canada" }
]
}Example - Multi Select:
{
"controlType": "select",
"name": "skills",
"label": "Select Your Skills",
"multiple": true,
"options": [
{ "label": "React", "value": "react" },
{ "label": "Node.js", "value": "node" },
{ "label": "Python", "value": "python" }
]
}Multi-line text input for longer content.
Key Properties:
rows- Number of visible text rows (default: 3)- Other common properties:
name,label,placeholder,required,disabled
Example:
{
"controlType": "textarea",
"name": "message",
"label": "Your Message",
"placeholder": "Type your message here...",
"rows": 5,
"required": true
}Interactive buttons for form submission and actions.
Key Properties:
buttonType- "submit", "reset", or "button"className- Tailwind CSS classes for styling- Other common properties:
name,label,disabled
Example:
{
"controlType": "button",
"name": "submitBtn",
"label": "Submit Form",
"buttonType": "submit",
"className": "bg-blue-600 text-white px-4 py-2 rounded"
}Every JSON configuration must have this root structure:
{
"fields": [
{ /* field object 1 */ },
{ /* field object 2 */ },
...
]
}{
"controlType": "input", // REQUIRED: Identifies component type
"inputType": "text", // Optional (varies by component)
"name": "fieldName", // Optional but recommended (unique identifier)
"label": "Field Label", // Optional (display label)
"placeholder": "Enter value", // Optional (works with input, textarea)
"required": true, // Optional (default: false)
"disabled": false, // Optional (default: false)
"defaultValue": "", // Optional (pre-fill value)
"className": "custom-class", // Optional (additional CSS classes)
"rows": 4, // Optional (textarea rows)
"min": 1, // Optional (numeric inputs)
"max": 100, // Optional (numeric inputs)
"step": 1, // Optional (numeric inputs)
"minLength": 3, // Optional (text inputs)
"maxLength": 50, // Optional (text inputs)
"accept": ".pdf", // Optional (file inputs)
"multiple": false, // Optional (file, select)
"options": [ // Optional (select, radio)
{ "label": "Option 1", "value": "opt1" },
{ "label": "Option 2", "value": "opt2" }
]
}1. Always use valid JSON syntax
- All keys and string values must use double quotes
- No trailing commas in objects or arrays
- Proper nesting and indentation
2. Use meaningful field names
- Use camelCase or snake_case consistently
- Make names descriptive:
fullName,email_address, notf1,e1 - Names help with form data identification
3. Order fields logically
- Group related fields together
- Put required fields first
- End with submit/action buttons
4. Provide helpful labels and placeholders
- Help users understand what each field expects
- Use placeholders to show format examples
- Labels must be clear and concise
5. Set appropriate constraints
- Use
requiredfor mandatory fields - Set
min/max/minLengthfor numeric and text validation - Use
acceptto filter file types
- Node.js ≥ 18 or later
- npm or yarn package manager
- Modern browser (Chrome/Edge/Firefox/Safari - current versions)
# Clone the repository
git clone https://github.com/yourusername/json-ui-builder.git
cd json-ui-builder
# Install dependencies
npm installDownload the source code and extract it, then:
cd json-ui-builder
npm installnpm run devThe application opens at http://localhost:5173 (Vite's default port).
Open your browser:
http://localhost:5173
- Left Panel: JSON Editor with default form template
- Right Panel: Live Preview of rendered form
- Bottom Panel: Error Console for JSON validation messages
Change any field value in the left panel and see the preview update instantly.
1. Paste your JSON configuration in the LEFT panel
↓
2. See LIVE PREVIEW on the RIGHT
↓
3. Check CONSOLE at bottom for errors
↓
4. Copy the rendered form or re-use JSON elsewhere
{
"fields": [
{
"controlType": "input",
"inputType": "text",
"name": "fullName",
"label": "Full Name",
"placeholder": "John Doe",
"required": true
},
{
"controlType": "input",
"inputType": "email",
"name": "email",
"label": "Email Address",
"placeholder": "john@example.com",
"required": true
},
{
"controlType": "input",
"inputType": "tel",
"name": "phone",
"label": "Phone Number",
"placeholder": "+1 (555) 123-4567"
},
{
"controlType": "textarea",
"name": "message",
"label": "Message",
"placeholder": "Tell us what you think...",
"rows": 4,
"required": true
},
{
"controlType": "button",
"name": "submit",
"label": "Send Message",
"buttonType": "submit",
"variant": "primary"
}
]
}{
"fields": [
{
"controlType": "input",
"inputType": "text",
"name": "username",
"label": "Username",
"placeholder": "Choose a username",
"required": true,
"minLength": 3,
"maxLength": 20
},
{
"controlType": "input",
"inputType": "email",
"name": "email",
"label": "Email",
"placeholder": "user@example.com",
"required": true
},
{
"controlType": "input",
"inputType": "password",
"name": "password",
"label": "Password",
"placeholder": "Minimum 8 characters",
"required": true,
"minLength": 8
},
{
"controlType": "input",
"inputType": "password",
"name": "confirmPassword",
"label": "Confirm Password",
"placeholder": "Re-enter your password",
"required": true
},
{
"controlType": "select",
"name": "country",
"label": "Country",
"required": true,
"options": [
{ "label": "United States", "value": "us" },
{ "label": "Canada", "value": "ca" },
{ "label": "United Kingdom", "value": "uk" },
{ "label": "India", "value": "in" }
]
},
{
"controlType": "checkbox",
"name": "newsletter",
"label": "Subscribe to our newsletter"
},
{
"controlType": "checkbox",
"name": "terms",
"label": "I agree to the terms and conditions",
"required": true
},
{
"controlType": "button",
"name": "registerBtn",
"label": "Create Account",
"buttonType": "submit",
"variant": "primary"
}
]
}{
"fields": [
{
"controlType": "input",
"inputType": "text",
"name": "fullName",
"label": "Full Name",
"required": true
},
{
"controlType": "input",
"inputType": "email",
"name": "email",
"label": "Email",
"required": true
},
{
"controlType": "input",
"inputType": "tel",
"name": "phone",
"label": "Phone Number"
},
{
"controlType": "input",
"inputType": "url",
"name": "portfolio",
"label": "Portfolio Website",
"placeholder": "https://yourportfolio.com"
},
{
"controlType": "select",
"name": "position",
"label": "Position Applied For",
"required": true,
"options": [
{ "label": "Frontend Developer", "value": "frontend" },
{ "label": "Backend Developer", "value": "backend" },
{ "label": "Full Stack Developer", "value": "fullstack" },
{ "label": "DevOps Engineer", "value": "devops" }
]
},
{
"controlType": "input",
"inputType": "number",
"name": "experience",
"label": "Years of Experience",
"min": 0,
"max": 50
},
{
"controlType": "select",
"name": "skills",
"label": "Technical Skills",
"multiple": true,
"options": [
{ "label": "React", "value": "react" },
{ "label": "Vue.js", "value": "vue" },
{ "label": "Node.js", "value": "nodejs" },
{ "label": "Python", "value": "python" },
{ "label": "Java", "value": "java" },
{ "label": "Docker", "value": "docker" }
]
},
{
"controlType": "file",
"name": "resume",
"label": "Upload Resume",
"accept": ".pdf,.doc,.docx",
"required": true
},
{
"controlType": "textarea",
"name": "coverLetter",
"label": "Cover Letter",
"rows": 6,
"placeholder": "Tell us why you're interested in this position..."
},
{
"controlType": "radio",
"name": "salaryExpectation",
"label": "Salary Expectation Range",
"options": [
{ "label": "$50k - $70k", "value": "50-70" },
{ "label": "$70k - $90k", "value": "70-90" },
{ "label": "$90k - $120k", "value": "90-120" },
{ "label": "$120k+", "value": "120+" }
]
},
{
"controlType": "checkbox",
"name": "relocation",
"label": "Open to relocation"
},
{
"controlType": "button",
"name": "submitBtn",
"label": "Submit Application",
"buttonType": "submit",
"variant": "primary"
}
]
}{
"fields": [
{
"controlType": "input",
"inputType": "text",
"name": "name",
"label": "Your Name",
"required": true
},
{
"controlType": "radio",
"name": "satisfaction",
"label": "How satisfied are you with our product?",
"required": true,
"options": [
{ "label": "Very Satisfied", "value": "5" },
{ "label": "Satisfied", "value": "4" },
{ "label": "Neutral", "value": "3" },
{ "label": "Dissatisfied", "value": "2" },
{ "label": "Very Dissatisfied", "value": "1" }
]
},
{
"controlType": "select",
"name": "features",
"label": "Which features do you use most?",
"multiple": true,
"options": [
{ "label": "Dashboard", "value": "dashboard" },
{ "label": "Analytics", "value": "analytics" },
{ "label": "Reports", "value": "reports" },
{ "label": "Integrations", "value": "integrations" }
]
},
{
"controlType": "range",
"name": "likelihood",
"label": "Likelihood to recommend (0-10)",
"min": 0,
"max": 10,
"step": 1
},
{
"controlType": "textarea",
"name": "feedback",
"label": "Additional Feedback",
"rows": 4,
"placeholder": "Tell us what we can improve..."
},
{
"controlType": "button",
"name": "submitBtn",
"label": "Submit Survey",
"buttonType": "submit",
"variant": "primary"
}
]
}For forms with many fields, organize them logically:
{
"fields": [
{
"controlType": "input",
"inputType": "text",
"name": "section1_field1",
"label": "Section 1 - Field 1",
"required": true
},
{
"controlType": "input",
"inputType": "text",
"name": "section2_field1",
"label": "Section 2 - Field 1"
}
]
}In the JSON Editor:
- Ctrl/Cmd + A - Select all
- Ctrl/Cmd + C - Copy
- Ctrl/Cmd + V - Paste
- Tab - Indent (2 spaces)
| Error | Cause | Solution |
|---|---|---|
Unexpected token |
Invalid JSON syntax | Check for trailing commas, missing quotes |
Invalid property |
Unrecognized field property | Only use supported properties for that component |
Cannot parse fields |
Missing fields array |
Ensure root structure has { "fields": [...] } |
Field name undefined |
Missing required controlType |
Every field needs "controlType" property |
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "JSON UI Builder Form Schema",
"type": "object",
"required": ["fields"],
"properties": {
"fields": {
"type": "array",
"description": "Array of form field definitions",
"items": {
"type": "object",
"required": ["controlType"],
"properties": {
"controlType": {
"type": "string",
"enum": [
"input",
"select",
"radio",
"checkbox",
"textarea",
"file",
"range",
"color",
"button"
],
"description": "Type of form control to render"
},
"inputType": {
"type": "string",
"enum": [
"text",
"email",
"password",
"number",
"tel",
"url",
"date",
"time",
"datetime-local",
"color",
"search",
"file"
],
"description": "HTML5 input type (for input control only)"
},
"name": {
"type": "string",
"description": "Unique field identifier for form submission"
},
"label": {
"type": "string",
"description": "Display label for the field"
},
"placeholder": {
"type": "string",
"description": "Placeholder text (for input and textarea)"
},
"required": {
"type": "boolean",
"default": false,
"description": "Mark field as required"
},
"disabled": {
"type": "boolean",
"default": false,
"description": "Disable field interaction"
},
"defaultValue": {
"oneOf": [
{ "type": "string" },
{ "type": "number" },
{ "type": "boolean" }
],
"description": "Pre-filled default value"
},
"className": {
"type": "string",
"description": "Additional CSS classes"
},
"min": {
"type": "number",
"description": "Minimum value (for numeric inputs)"
},
"max": {
"type": "number",
"description": "Maximum value (for numeric inputs)"
},
"step": {
"type": "number",
"description": "Step increment (for range, number inputs)"
},
"minLength": {
"type": "number",
"description": "Minimum character length"
},
"maxLength": {
"type": "number",
"description": "Maximum character length"
},
"rows": {
"type": "number",
"description": "Number of rows (for textarea)"
},
"accept": {
"type": "string",
"description": "Accepted file types (.pdf, .jpg, etc.)"
},
"multiple": {
"type": "boolean",
"default": false,
"description": "Allow multiple selections or file uploads"
},
"options": {
"type": "array",
"description": "Options for select, radio, checkbox",
"items": {
"type": "object",
"required": ["label", "value"],
"properties": {
"label": {
"type": "string",
"description": "Display text for option"
},
"value": {
"oneOf": [
{ "type": "string" },
{ "type": "number" }
],
"description": "Value when option is selected"
}
}
}
},
"buttonType": {
"type": "string",
"enum": ["submit", "reset", "button"],
"default": "button",
"description": "Button type (for button control only)"
},
"variant": {
"type": "string",
"enum": ["primary", "secondary"],
"description": "Button style variant"
}
}
}
}
}
}JSON UI Builder uses TailwindCSS for styling. All components are pre-styled with:
- Consistent color palette (slate, indigo, emerald, red)
- Responsive breakpoints (mobile-first design)
- Modern rounded corners and shadows
- Accessibility-focused defaults
/* Built-in styles include: */
border: 1px solid #e2e8f0 (slate-200)
padding: 10px 16px (px-4 py-2.5)
border-radius: 12px (rounded-xl)
background: white
focus: ring-4 ring-blue-500/10/* Primary variant */
background: indigo-600
hover: bg-indigo-700
text-white
padding: 10px 24px
/* Secondary variant */
background: gray-200
hover: bg-gray-300
text-slate-900Currently, you can add custom classes via the className property:
{
"controlType": "input",
"name": "email",
"label": "Email",
"className": "bg-blue-50 border-blue-300"
}Note: This requires modifying component source code. Full CSS customization is planned for future versions.
| Element | Color | TailwindCSS Class |
|---|---|---|
| Primary | Indigo | indigo-600 |
| Success | Emerald | emerald-500 |
| Error | Red | red-500 |
| Warning | Amber | amber-500 |
| Neutral | Slate | slate-500 |
| Background | Light Slate | slate-50 to slate-100 |
All forms are mobile-first and include responsive breakpoints:
- Mobile (default)
- Tablet (md: 768px)
- Desktop (lg: 1024px)
- Large Desktop (xl: 1280px)
The editor and preview panels stack on mobile and sit side-by-side on larger screens.
json-ui-builder/
├── public/ # Static assets
│ ├── vite.svg
│ └── favicon.ico
│
├── src/
│ ├── components/ # React components
│ │ ├── Console.jsx # Error console display
│ │ ├── JsonEditor.jsx # JSON input editor (contentEditable)
│ │ ├── LayoutCases.jsx # Component routing (switch statement)
│ │ ├── Preview.jsx # Form preview renderer
│ │ └── ui/ # Reusable UI components
│ │ ├── Input.jsx # Styled input wrapper
│ │ └── Select.jsx # Styled select wrapper
│ │
│ ├── constants/ # Configuration & defaults
│ │ └── index.js # DefaultInputs export
│ │
│ ├── pages/ # Page components
│ │ └── JsonUiBuilder.jsx # Main app page (state management)
│ │
│ ├── App.jsx # App entry point (routing)
│ ├── App.css # Global styles
│ ├── main.jsx # React DOM render
│ ├── index.css # Reset styles
│ └── Test.jsx # Testing component (unused)
│
├── index.html # HTML template
├── package.json # Dependencies & scripts
├── vite.config.js # Vite build configuration
├── eslint.config.js # ESLint rules
└── README.md # This file
Main application component. Handles:
- JSON input state management
- Real-time parsing with useMemo
- Error state management
- Layout composition
Field type routing. Contains switch statement mapping:
input→ Input componentselect→ Select dropdownradio→ Radio button groupcheckbox→ Checkbox inputtextarea→ Textarea fieldfile→ File uploadrange→ Range slidercolor→ Color pickerbutton→ Button element
contentEditable div that allows real-time JSON editing with:
- No external dependencies required
- Sync between state and DOM
- Syntax highlighting support (can be extended)
Exports:
DefaultInputs- Default form template with all component examples
App
├── Routes
│ ├── Route (/)
│ │ └── JsonUiBuilder (main page)
│ │ ├── JsonEditor (left panel)
│ │ ├── Preview (right panel)
│ │ │ └── LayoutCases (maps field types)
│ │ │ ├── Input
│ │ │ ├── Select
│ │ │ ├── Radio group
│ │ │ ├── Checkbox
│ │ │ ├── Textarea
│ │ │ ├── File upload
│ │ │ ├── Range slider
│ │ │ ├── Color picker
│ │ │ └── Button
│ │ └── Console (bottom panel)
│ └── Route (/docs) - placeholder
npm run devStarts Vite development server with hot module replacement (HMR).
- Opens at
http://localhost:5173 - Reloads automatically on file changes
npm run buildCreates optimized production build:
- Minifies code
- Tree-shakes unused imports
- Optimizes bundle size
- Output in
dist/directory
npm run previewServes the production build locally for testing:
- Useful for testing production-like environment
- Opens at
http://localhost:4173
npm run lintRuns ESLint to check code quality:
- Detects syntax errors
- Enforces React best practices
- Shows warnings and errors
npm installInstalls or updates all project dependencies from package.json.
# 1. Install dependencies
npm install
# 2. Start development server
npm run dev
# 3. In another terminal, run lint checker (optional)
npm run lint
# 4. When ready to deploy, build for production
npm run build
# 5. Test production build locally
npm run previewSteps:
- Push code to GitHub
- Go to vercel.com
- Click "New Project"
- Import your GitHub repository
- Vercel auto-detects Vite
- Click "Deploy"
Environment:
- Auto-deployed on every push to main
- Preview deployments for pull requests
- Free tier includes generous limits
Custom Domain:
- Go to project settings
- Add your domain under "Domains"
- Update DNS records as instructed
Steps:
- Push code to GitHub
- Go to netlify.com
- Click "New site from Git"
- Connect to GitHub
- Set build command:
npm run build - Set publish directory:
dist - Click "Deploy"
Custom Domain:
- Domain settings → Add domain
- Update DNS records
Steps:
- Update
vite.config.js:
export default defineConfig({
base: '/json-ui-builder/', // Replace with your repo name
plugins: [react(), tailwindcss()],
});- Deploy script (add to
package.json):
{
"scripts": {
"deploy": "npm run build && npx gh-pages -d dist"
}
}- Run:
npm install --save-dev gh-pages
npm run deploy- In GitHub repository settings:
- Go to Pages
- Set source to "gh-pages" branch
Dockerfile:
# Build stage
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
# Production stage
FROM node:18-alpine
WORKDIR /app
RUN npm install -g serve
COPY --from=builder /app/dist ./dist
EXPOSE 3000
CMD ["serve", "-s", "dist", "-l", "3000"]Build and run:
docker build -t json-ui-builder .
docker run -p 3000:3000 json-ui-builderSteps:
- Build the project:
npm run build- Install serve:
npm install -g serve-
Deploy
dist/folder to your server -
Run:
serve -s dist -l 3000If needed, create a .env file:
VITE_API_URL=https://api.example.com
VITE_APP_NAME=JSON UI BuilderAccess in code:
const apiUrl = import.meta.env.VITE_API_URL;- Enable GZIP compression on your hosting
- Set cache headers for static assets
- Use CDN (Vercel/Netlify do this automatically)
- Monitor bundle size:
npm run buildshows bundle analysis
- Memoized Parsing
const parsed = useMemo(() => {
// Heavy JSON parsing only when jsonInput changes
return JSON.parse(jsonInput);
}, [jsonInput]);- Key-based Rendering
{parsed.fields?.map((field) => (
<LayoutCases key={field.name || field.label} field={field} />
))}- Component-Level Optimization
- TailwindCSS for zero-runtime styling
- No external UI libraries affecting bundle size
- React Router for code splitting
Current bundle analysis:
- React: ~40KB
- React DOM: ~35KB
- React Router: ~50KB
- TailwindCSS: ~25KB
- Application Code: ~15KB
- Total Gzipped: ~70KB
- Limit field count - 50+ fields may cause lag
- Avoid deeply nested JSON - Keep flat structure
- Use simple labels - Avoid large objects in field properties
- Browser DevTools - Use Performance tab to profile
| Field Count | Parse Time | Render Time | DOM Size |
|---|---|---|---|
| 5 | <1ms | <5ms | ~2KB |
| 20 | 1-2ms | 10-15ms | ~8KB |
| 50 | 2-3ms | 30-50ms | ~20KB |
| 100+ | 5-10ms | 100-200ms | ~40KB+ |
Recommendation: Keep forms under 50 fields for optimal performance.
| Browser | Minimum Version | Notes |
|---|---|---|
| Chrome | Latest (current) | Fully supported |
| Edge | Latest (current) | Fully supported |
| Firefox | Latest (current) | Fully supported |
| Safari | Latest (current) | Fully supported |
| Opera | Latest (current) | Fully supported |
| Feature | Chrome | Edge | Firefox | Safari |
|---|---|---|---|---|
| React 19 | ✅ | ✅ | ✅ | ✅ |
| ES2020+ | ✅ | ✅ | ✅ | ✅ |
| contentEditable | ✅ | ✅ | ✅ | ✅ |
| JSON.parse | ✅ | ✅ | ✅ | ✅ |
| CSS Grid | ✅ | ✅ | ✅ | ✅ |
To test specific browser versions:
-
Chrome DevTools:
- Press F12
- Cmd/Ctrl + Shift + M (mobile view)
- Click device dropdown
-
BrowserStack: Remote testing on real devices
- Safari: Minor shadow rendering differences (cosmetic only)
- Mobile Safari: Keyboard may cover editor (workaround: scroll up)
- Older browsers: Not supported (requires ES2020+ features)
❌ No Conditional Fields
- Cannot show/hide fields based on other field values
- All fields are always rendered
- Workaround: Create separate JSON configs for different scenarios
❌ No Nested/Grouped Fields
- All fields are flat at root level
- No support for fieldsets or sections
- Workaround: Use naming conventions (e.g.,
section_fieldname)
❌ No Form State Management
- Form data is not captured or stored
- No form submission functionality
- No local storage persistence
- Workaround: Implement separately or use custom components
❌ No Custom Components
- Only built-in components supported
- Cannot register custom React components
- Workaround: Fork the repo and add custom components
❌ No Advanced Validation
- No regex patterns
- No async validation (e.g., checking email availability)
- No cross-field validation
- Current Support: Basic required, min/max, minLength/maxLength only
❌ No Theming System
- Cannot change color schemes dynamically
- Styling is TailwindCSS only
- Workaround: Modify CSS or fork the repo
❌ No Multi-Language Support
- All text is in English
- No i18n integration
- Workaround: Implement separately
❌ No Dark Mode
- Only light theme available
- Planned for: Future version
❌ No Form Reset Functionality
- Reset button renders but doesn't clear fields
- Status: Visual placeholder only
❌ No Button Click Handlers
- Buttons are visual placeholders
- No submit, reset, or custom actions
- Status: Rendering mockup only
- Must be valid JSON (no comments)
- No JSON5 or extended syntax
- Numbers and strings only in option values
- Not tested on Internet Explorer
- Mobile keyboard may cover small screens
- Not optimized for very small phones (<320px)
- Forms with 100+ fields show lag
- Very large JSON files (>500KB) may be slow
- No virtualization for large field lists
- Form Data Capture - Collect form values in real-time
- Export Functionality - Download form data as JSON/CSV
- Local Storage - Persist JSON config in browser
- Syntax Highlighting - JSON editor with color coding
- Conditional Fields - Show/hide based on form state
- Field Grouping - Section/tabs support
- Custom Validators - Regex and custom validation rules
- Dark Mode - Theme toggle
- Custom Components - Register and use custom React components
- Nested Fields - Support for object properties
- Template Library - Pre-built form templates
- API Integration - Form submission to backend
- Internationalization - Multi-language support
-
Advanced Features:
- Conditional branching logic
- Field dependencies and relationships
- Async field validation
- File upload handling
- State management integration (Redux, Zustand)
-
Developer Experience:
- TypeScript support
- NPM package export
- Storybook integration
- API documentation
-
Enterprise Features:
- Permission controls
- Audit logging
- Versioning system
- Team collaboration
We're open to contributions! Areas we need help with:
- Testing - Add unit and integration tests
- Documentation - Improve guides and examples
- Components - Submit new component requests
- Translations - Help with multi-language support
- Performance - Optimize rendering and bundle size
- Fork the repository
git clone https://github.com/yourusername/json-ui-builder.git- Create a feature branch
git checkout -b feature/your-feature-name- Make your changes
- Follow code style conventions
- Add comments for complex logic
- Test your changes
- Commit with clear messages
git commit -m "feat: add new feature"
git commit -m "fix: resolve bug"- Push and create a Pull Request
git push origin feature/your-feature-name- We'll review and merge!
- Use 2 spaces for indentation
- Use camelCase for variables
- Use PascalCase for components
- Use UPPER_SNAKE_CASE for constants
- Keep components focused and single-responsibility
Before submitting, test your changes:
npm run lint # Check code quality
npm run build # Verify production build
npm run preview # Test the buildFound an issue? Please open an issue on GitHub with:
- Clear description of the bug
- Steps to reproduce
- Expected vs actual behavior
- Browser and OS info
- Screenshots (if visual)
Have an idea? Open an issue with:
- Clear title and description
- Use case and benefit
- Example JSON if applicable
- Any relevant context
This project is licensed under the MIT License - see LICENSE file for details.
- ✅ Use commercially
- ✅ Modify the code
- ✅ Distribute
- ✅ Use privately
⚠️ Include the original license
- Check Documentation - This README covers most use cases
- Search Issues - GitHub issues may have your answer
- Open an Issue - Ask the community
- Join Community - Discuss on discussions tab
Built with:
- React - UI library
- Vite - Build tool
- TailwindCSS - Styling
- React Router - Navigation
// Input
{ "controlType": "input", "inputType": "text|email|password|number|date|etc" }
// Select
{ "controlType": "select", "options": [{"label": "A", "value": "a"}] }
// Radio
{ "controlType": "radio", "options": [{"label": "A", "value": "a"}] }
// Checkbox
{ "controlType": "checkbox" }
// Textarea
{ "controlType": "textarea", "rows": 4 }
// File
{ "controlType": "file", "accept": ".pdf", "multiple": false }
// Range
{ "controlType": "range", "min": 0, "max": 100, "step": 1 }
// Color
{ "controlType": "color" }
// Button
{ "controlType": "button", "buttonType": "submit" }{
"name": "field_id", // Identifier
"label": "Field Label", // Display label
"placeholder": "Hint text", // Placeholder
"required": true, // Required field
"disabled": false, // Disabled state
"defaultValue": "default", // Pre-fill
"className": "extra-class" // Custom classes
}{
"min": 1, // Numeric minimum
"max": 100, // Numeric maximum
"minLength": 3, // String minimum length
"maxLength": 50, // String maximum length
"step": 1, // Numeric step size
"accept": ".pdf" // File type filter
}- Core JSON-to-UI conversion
- 9 built-in components
- Real-time validation
- Live preview
- Developer console
- TailwindCSS styling
We'd love to hear from you! Share feedback:
- Open an Issue on GitHub
- Start a Discussion for feature ideas
- Create a Pull Request to contribute code
- Share your use cases to inspire improvements
| Term | Definition |
|---|---|
| controlType | The type of form component to render |
| inputType | HTML5 input type when controlType is "input" |
| Field | A single form control (input, select, etc.) |
| Parse | Convert JSON string to JavaScript object |
| Render | Display components in the browser |
| Mutate | Change component state (e.g., checked/unchecked) |
| Props | Properties passed to React components |
| HMR | Hot Module Replacement - reload without full refresh |
| Props Spreading | Using {...props} to pass multiple props at once |
Last Updated: March 2026
Maintained By: Dishank Patel
Repository: github.com/19dishank/json-ui-builder