FormCraft
Build type-safe, dynamic forms in Blazor with an elegant fluent API. FormCraft simplifies complex form creation with automatic field rendering, validation, and dependency management. Features include customizable field renderers, async validation, conditional visibility, and seamless MudBlazor integration.
Install / Use
/learn @phmatray/FormCraftREADME
FormCraft 🎨
<div align="center">Build type-safe, dynamic forms in Blazor with ease ✨
Get Started • Live Demo • Documentation • Examples • Contributing
</div>🌐 Live Demo
Experience FormCraft in action! Visit our interactive demo to see:
- 🎯 Various form layouts and configurations
- 🔄 Dynamic field dependencies
- ✨ Custom field renderers
- 📤 File upload capabilities
- 🎨 Real-time form generation
🎉 What's New in v2.5.0
FormCraft v2.5.0 introduces powerful attribute-based form generation and more:
🏷️ Attribute-Based Form Generation (NEW!)
- Zero-configuration forms - Generate complete forms from model attributes
- Rich attribute library - TextField, EmailField, NumberField, DateField, SelectField, CheckboxField, TextArea
- Automatic validation - Integrates with DataAnnotations attributes
- One-line setup - Just call
.AddFieldsFromAttributes()
🔒 Security Features (v2.0.0)
- Field-level encryption for sensitive data protection
- CSRF protection with built-in anti-forgery tokens
- Rate limiting to prevent form spam
- Audit logging to track all form interactions
📦 Modular Architecture
- Separate UI framework packages - Use only what you need
- FormCraft.ForMudBlazor - MudBlazor implementation package
- Improved extensibility - Easier to add custom UI frameworks
🚀 Other Improvements
- Enhanced performance with optimized rendering
- Better type safety with improved generic constraints
- Comprehensive documentation with live examples
- 550+ unit tests ensuring reliability
🚀 Why FormCraft?
FormCraft revolutionizes form building in Blazor applications by providing a fluent, type-safe API that makes complex forms simple. Say goodbye to repetitive form markup and hello to elegant, maintainable code.
✨ Key Features
- 🔒 Type-Safe - Full IntelliSense support with compile-time validation
- 🎯 Fluent API - Intuitive method chaining for readable form configuration
- 🏷️ Attribute-Based Forms - Generate forms from model attributes with zero configuration
- 🎨 MudBlazor Integration - Beautiful Material Design components out of the box
- 🔄 Dynamic Forms - Create forms that adapt based on user input
- ✅ Advanced Validation - Built-in, custom, and async validators
- 🔗 Field Dependencies - Link fields together with reactive updates
- 📐 Flexible Layouts - Multiple layout options to fit your design
- 🚀 High Performance - Optimized rendering with minimal overhead
- 🧪 Fully Tested - 550+ unit tests ensuring reliability
📊 How FormCraft Compares
FormCraft stands out among Blazor form solutions with its type-safe fluent API, automatic field rendering, and built-in field dependency management. See how it compares to Blazor EditForm, Blazored.FluentValidation, and MudBlazor Forms:
| Capability | EditForm | MudBlazor Forms | FormCraft | |------------|:--------:|:---------------:|:---------:| | Fluent API configuration | - | - | Yes | | Automatic field rendering | - | - | Yes | | Built-in field dependencies | Manual | Manual | Yes | | Conditional visibility | Manual | Manual | Built-in | | Field-level encryption | - | - | Yes | | Attribute-based generation | - | - | Yes |
View the full comparison — includes detailed feature matrix, code examples, and guidance on when to use each solution.
📦 Installation
FormCraft Core
dotnet add package FormCraft
FormCraft for MudBlazor
dotnet add package FormCraft.ForMudBlazor
Note: FormCraft.ForMudBlazor includes FormCraft as a dependency, so you only need to install the MudBlazor package if you're using MudBlazor components.
🎯 Quick Start
1. Register Services
// Program.cs
builder.Services.AddFormCraft();
2. Create Your Model
public class UserRegistration
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public int Age { get; set; }
public string Country { get; set; }
public bool AcceptTerms { get; set; }
}
3. Build Your Form
@page "/register"
@using FormCraft
@using FormCraft.ForMudBlazor
<h3>User Registration</h3>
<FormCraftComponent TModel="UserRegistration"
Model="@model"
Configuration="@formConfig"
OnValidSubmit="@HandleSubmit"
ShowSubmitButton="true" />
@code {
private UserRegistration model = new();
private IFormConfiguration<UserRegistration> formConfig;
protected override void OnInitialized()
{
formConfig = FormBuilder<UserRegistration>.Create()
.AddRequiredTextField(x => x.FirstName, "First Name")
.AddRequiredTextField(x => x.LastName, "Last Name")
.AddEmailField(x => x.Email)
.AddNumericField(x => x.Age, "Age", min: 18, max: 120)
.AddSelectField(x => x.Country, "Country", GetCountries())
.AddCheckboxField(x => x.AcceptTerms, "I accept the terms and conditions")
.IsRequired("You must accept the terms")
.Build();
}
private async Task HandleSubmit(UserRegistration model)
{
// Handle form submission
await UserService.RegisterAsync(model);
}
private List<SelectOption<string>> GetCountries() => new()
{
new("us", "United States"),
new("uk", "United Kingdom"),
new("ca", "Canada"),
new("au", "Australia")
};
}
🏷️ Attribute-Based Forms (NEW!)
Define your forms directly on your model with attributes - no configuration code needed!
Define Your Model with Attributes
public class UserRegistration
{
[TextField("First Name", "Enter your first name")]
[Required(ErrorMessage = "First name is required")]
[MinLength(2)]
public string FirstName { get; set; } = string.Empty;
[TextField("Last Name", "Enter your last name")]
[Required(ErrorMessage = "Last name is required")]
public string LastName { get; set; } = string.Empty;
[EmailField("Email Address")]
[Required]
public string Email { get; set; } = string.Empty;
[NumberField("Age", "Your age")]
[Range(18, 120, ErrorMessage = "Age must be between 18 and 120")]
public int Age { get; set; }
[DateField("Date of Birth")]
public DateTime BirthDate { get; set; }
[SelectField("Country", "United States", "Canada", "United Kingdom", "Australia")]
public string Country { get; set; } = string.Empty;
[TextArea("Bio", "Tell us about yourself")]
[MaxLength(500)]
public string Bio { get; set; } = string.Empty;
[CheckboxField("Newsletter", "Subscribe to our newsletter")]
public bool SubscribeToNewsletter { get; set; }
}
Generate the Form with One Line
var formConfig = FormBuilder<UserRegistration>.Create()
.AddFieldsFromAttributes() // That's it! 🎉
.Build();
Available Attribute Types
[TextField]- Standard text input[EmailField]- Email input with validation[NumberField]- Numeric input with min/max support[DateField]- Date picker with constraints[SelectField]- Dropdown with predefined options[CheckboxField]- Boolean checkbox[TextArea]- Multiline text input
All attributes work seamlessly with standard DataAnnotations validators like [Required], [MinLength], [MaxLength], [Range], and more!
Comparison: Fluent API vs Attributes
<table> <tr> <th>Fluent API</th> <th>Attribute-Based</th> </tr> <tr> <td>var config = FormBuilder<User>.Create()
.AddField(x => x.Name, field => field
.WithLabel("Full Name")
.WithPlaceholder("Enter name")
.Required("Name is required")
.WithMinLength(2))
.AddField(x => x.Email, field => field
.WithLabel("Email")
.WithInputType("email")
.Required())
.Build();
</td>
<td>
public class User
{
[TextField("Full Name", "Enter name")]
[Required(ErrorMessage = "Name is required")]
[MinLength(2)]
public string Name { get; set; }
[EmailField("Email")]
[Required]
public string Email { get; set; }
}
// One line to generate!
var config = FormBuilder<User>.Create()
.AddFieldsFromAttributes()
.Build();
</td>
</tr>
</table>
🎨 Examples
Dynamic Field Dependencies
Create forms where fields react to each other:
var formConfig = FormBuilder<OrderForm>.Create()
.AddSelectField(x => x.ProductType, "Product Type", productOptions)
.AddSelectField(x => x.ProductModel, "Model",
dependsOn: x => x.ProductType,
optionsProvider: (productType) => GetModelsForType(productType))
.AddNumericField(x => x.Quan
