The Formulaik
project
An open source initiative for defining cross-platform forms, enabling reusable components in a JSON based declarative approach. Formulaik aims to simplify form building across various front-end frameworks. Formulaik defines a protocol for defining form inputs as a sole source of truth (data type, behaviour, validation) in json, which is interpreted by a platform-specific formulaik engine.
🍨
Declarative
The JSON based form declaration is what separates Formulaik from other frameworks. Simply give an array of inputs and component libraries to find their implementation.
Predictable, scalable clean forms
Every input component follows a unique API that make it readable, testable, maintainable and shippable.
Extensible
The component libraries system makes it easy to use a feature team, a project, a company or a community library to jump start a project.
Quick start 🚀
Let's build a login form with email and password inputs.
- React JS
- React Native
- Swift
- Kotlin
- Flutter
- Vue JS
1. Install formulaik and a component library
- npm
- yarn
npm install @formulaik/react @formulaik-community/react-mui
yarn add @formulaik/react @formulaik-community/react-mui
2. Define inputs
const inputs = [
{
component: 'input',
id: 'email',
label: 'Email',
type: "string",
params: {
type: 'email',
placeholder: "email@domain.com"
},
validations: [
{
kind: "format",
value: "email",
message: 'Invalid email format',
},
{
kind: "required",
value: true,
message: "This field can't be blank",
},
],
},
{
component: 'inputPassword',
label: 'Password',
id: 'password',
type: "string",
params: {
type: 'password',
autoComplete: "current-password",
placeholder: "xxxx-xxxx-xxxx"
},
validations: [
{
kind: "matches",
value: /^(?=.*d)(?=.*[a-z])(?=.*[A-Z])(?=.*[a-zA-Z]).{8,}$/,
message: 'Invalid password, must contain at least 8 characters and at most 18 characters',
},
{
kind: "required",
value: true,
message: "This field can't be blank",
},
]
},
{
component: 'submit',
params: {
text: 'Continue'
}
},
]
3. Provide initial values (optional)
const values = {
email: cookies.get('email'),
}
4. Render forms and handle submit
import Formulaik from '@formulaik/react'
import FormulaikMui from '@formulaik-community/react-mui'
export default (props) => {
const onSubmit = async (values) => {
const { email, password } = values
try {
await myapi.submit({ email, password })
}
catch(e) {
throw (new Error('Could not sign in: ', e.message))
}
return { message: t("Email validated") }
}
return <>
<h3>Login</h3>
<Formulaik
components={[FormulaikMui]}
values={values}
inputs={inputs}
onSubmit={onSubmit}
/>
</>
}
1. Install formulaik and a component library
- npm
- yarn
npm install @formulaik/react-native @formulaik-community/react-native-elements
yarn add @formulaik/react-native @formulaik-community/react-native-elements
2. Define inputs
const inputs = [
{
component: 'input',
id: 'email',
label: 'Email',
type: "string",
params: {
type: 'email',
placeholder: "email@domain.com"
},
validations: [
{
kind: "format",
value: "email",
message: 'Invalid email format',
},
{
kind: "required",
value: true,
message: "This field can't be blank",
},
],
},
{
component: 'inputPassword',
label: 'Password',
id: 'password',
type: "string",
params: {
type: 'password',
autoComplete: "current-password",
placeholder: "xxxx-xxxx-xxxx"
},
validations: [
{
kind: "matches",
value: /^(?=.*d)(?=.*[a-z])(?=.*[A-Z])(?=.*[a-zA-Z]).{8,}$/,
message: 'Invalid password, must contain at least 8 characters and at most 18 characters',
},
{
kind: "required",
value: true,
message: "This field can't be blank",
},
]
},
{
component: 'submit',
params: {
text: 'Continue'
}
},
]
3. Provide initial values (optional)
const values = {
email: cookies.get('email'),
}
4. Render forms and handle submit
import Formulaik from '@formulaik/react'
import FormulaikElements from '@formulaik-community/react-native-elements'
import { Text } from 'react-native'
export default (props) => {
const onSubmit = async (values) => {
const { email, password } = values
try {
await myapi.submit({ email, password })
}
catch(e) {
throw (new Error('Could not sign in: ', e.message))
}
return { message: t("Email validated") }
}
return <>
<Text>Login</Text>
<Formulaik
components={[FormulaikElements]}
values={values}
inputs={inputs}
onSubmit={onSubmit}
/>
</>
}
Not available yet.
Want to contribute? Join the movement.Not available yet.
Want to contribute? Join the movement.Not available yet.
Want to contribute? Join the movement.Not available yet.
Want to contribute? Join the movement.Decouple your form declaration from its implementation 🖖
Go from having your form inputs behavior cluttered in a React file to a clear separation of concerns between declaration via a JSON and component libraries.
Break the Form into Small Reusable Components
Formulaik's architecture helps you define your input components in separated files and register them in a component library.
Declare once, use everywhere
Formulaik inputs are pure JSON so that the component they use, the validations and the customizations are easy to read, update and maintain.
Multi-platform
On React and React-native we use the powerful Formik library for rendering the inputs. We look forward to making Formulaik available on other major platforms.
What do we want?
Ok, what would the perfect CLI generator look like ?
- Easy to read
- Easy to debug
- Separate declaration from implementation
- Reuse components in a project
- Reuse component libraries across projects
- Have a unique multi-platform specification and behavior of our forms