Blueprints are Domma's unified schema system. Define your data structure once, then use it everywhere:
Built-in + custom
Auto-generation
Reactive data
Complete system
A blueprint is a JavaScript object defining field types, validation, and UI configuration.
const userBlueprint = {
name: {
type: 'string', // Field type
required: true, // Validation
minLength: 2,
maxLength: 50,
label: 'Full Name', // Form config
placeholder: 'Enter name'
},
email: {
type: 'email',
required: true,
label: 'Email Address',
validate: (value) => { // Custom validator
return /\S+@\S+/.test(value) || 'Invalid email';
}
},
age: {
type: 'number',
min: 0,
max: 120,
label: 'Age'
},
active: {
type: 'boolean',
default: true,
label: 'Active User'
}
};
Domma provides 7 built-in types for common data structures:
M.types.string
Text data
M.types.number
Numeric values
M.types.boolean
True/false
M.types.array
Lists
M.types.object
Nested data
M.types.date
Timestamps
M.types.any
No validation
Explore pre-built blueprints for common use cases.
Control form layout and field appearance using formConfig properties.
F.render('#form', blueprint, {}, {
layout: 'grid', // or 'stacked', 'inline'
columns: 2, // 2 or 3 columns (grid only)
labelPosition: 'top', // or 'left', 'floating'
showLabels: true,
showHelperText: true
});
fieldName: {
type: 'string',
required: true,
label: 'Field Label',
formConfig: {
span: 2, // Span 2 columns
placeholder: 'Text', // Placeholder
helperText: 'Help', // Below field
hint: '(optional)', // Next to label
tooltip: 'Info', // Hover tooltip (NEW!)
disabled: false // Disable field
}
}
Use layout: 'grid' with columns: 2 and formConfig.span to control field width:
const addressBlueprint = {
street: {
type: 'string',
required: true,
label: 'Street Address',
formConfig: { span: 2 } // Full width (spans 2 columns)
},
city: {
type: 'string',
required: true,
label: 'City'
// No span = takes 1 column (left side)
},
postcode: {
type: 'string',
required: true,
label: 'Postcode'
// No span = takes 1 column (right side)
},
country: {
type: 'select',
options: ['UK', 'USA', 'Canada'],
label: 'Country',
formConfig: { span: 2 } // Full width
}
};
// Render with grid layout
F.render('#form', addressBlueprint, {}, {
layout: 'grid',
columns: 2
});
Automatically generate forms from blueprints with full validation.
const contactBlueprint = {
name: {
type: 'string',
required: true,
minLength: 2,
label: 'Full Name'
},
email: {
type: 'email',
required: true,
label: 'Email'
},
message: {
type: 'textarea',
required: true,
minLength: 10,
rows: 4,
label: 'Message'
}
};
// Generate and render form (one-step)
F.render(
'#contact-form', // selector
contactBlueprint, // schema
{}, // initial data
{ // options
layout: 'stacked',
onSubmit: (data) => {
console.log(data);
}
}
);
Create reactive data models with automatic validation and change tracking.
const user = M.create(userBlueprint, {
name: 'Alice',
email: 'alice@example.com',
age: 30
});
// Get values
user.get('name'); // 'Alice'
// Set values
user.set('age', 31);
// Validate
const errors = user.validate();
// Listen for changes
user.onChange((event) => {
console.log(event);
});
{}
No changes yet
Combine, extend, and modify blueprints with composition methods.
const base = {
name: { type: 'string' },
email: { type: 'email' }
};
const extended = {
email: { required: true },
age: { type: 'number' }
};
const result = B.extend(base, extended);
// { name: {...}, email: {required: true}, age: {...} }
const full = {
name: { type: 'string' },
email: { type: 'email' },
age: { type: 'number' },
role: { type: 'string' }
};
const subset = B.pick(full, ['name', 'email']);
// { name: {...}, email: {...} }
const admin = {
name: { type: 'string' },
email: { type: 'email' },
role: { type: 'string' },
permissions: { type: 'array' }
};
const public = B.omit(admin, ['permissions']);
// { name: {...}, email: {...}, role: {...} }
Blueprints power complete CRUD interfaces with tables, forms, and API integration.
A typical CRUD setup with blueprints includes: