Guide: creating custom fields

It's possible to create custom fields. A field needs a constructor function that users call to create instances of it in their configuration.

Range field example

Let's create a custom field to demonstrate.

import {alinea} from 'alinea'
import {Field, Hint, Label, Shape} from '@alinea/core'
import {InputLabel, InputState, useInput} from '@alinea/editor'

export interface RangeFieldOptions {
  min?: number
  max?: number

export interface RangeField extends Field.Scalar<number> {
  label: Label
  options?: RangeFieldOptions

// The constructor function is used to create fields in our schema
// later on. It is usually passed a label and options.
export function range(label: Label, options?: RangeFieldOptions): RangeField {
  return {
    shape: Shape.Scalar(label),
    view: RangeInput,
    hint: Hint.Number()

interface RangeInputProps {
  state: InputState<InputState.Scalar<number>>
  field: RangeField

// To view our field we can create a React component. 
// This component can call the useInput hook to receive the
// current value and a method to update it.
function RangeInput({state, field}: RangeInputProps) {
  const [value = 5, setValue] = useInput(state)
  const {min = 0, max = 10} = field.options || {}
  return (
    <InputLabel label={field.label}>
        min={min} max={max} 
        onChange={e => setValue(Number(} 

To use the field in your types later just call the constructor function:

alinea.type('My type', {
  range: range('A range field', {min: 0, max: 20})


To structure the underlying data we use shapes. Alinea ships with four kinds of shape primitives that can be nested inside each other. Under the covers these are created via Yjs allowing them to be fully collaborative.


Scalar values hold a single value that is overwritten anytime it is changed.


A record value store an object with data. The object values can take any shape.


A list holds an array of values, which must be record shapes. Every item in a list has a type, an automatically generated id and an index for sorting added on.

Rich text

Rich text is an xml like structure that can hold wysiwyg data.