Skip to content
Roberto Ferranti edited this page Nov 3, 2026 · 15 revisions

fml

A frontend library with no build step and no dependencies: plain ES modules and script tags, everything the browser already gives you, plus the four pieces it does not.

  • ftl: templating and web components. data-tpl-* attributes, a small expression language over a PEG grammar, and a registry that upgrades your elements once the page is parsed.
  • httpc: an http client with a composable request builder, interceptors, and a problems error contract that maps error responses to typed failures.
  • ful: 29 web components for forms and flows, built on ftl and httpc. Inputs, selects, files, temporals, filters, tables with pagination and sorting, plus disclosures (tooltips, dialogs, drawers, menus), toasts and navigation (tabs, accordion, wizard). Self-contained css, themed through custom properties, localized in en/it/es/fr.
  • client-errors: a one-tag script that reports uncaught errors and unhandled rejections to your endpoint, cause chain included.

The four libraries ship as one package, @optionfactory/fml. A page loads them as a single IIFE (globals ftl, httpc, ful), as individual IIFEs, or as ES modules, either through a bundler's subpath exports or straight into the page through an import map. Getting started shows each, and what each costs.

a ful form: an input with affixes, a select, a switch, a submit button

Reading order

The wiki has three entry points, depending on what you are doing.

you are start at
putting fml elements on a page Getting started, then ful getting started
writing elements, fields or loaders of your own Concepts, then the extension pages
looking up one attribute, event or slot Element reference

Concepts is the page to read if you only read one: it states the rendering model, the component model, the field model, the failure model and the styling model in one place, along with the design decisions behind each and what they mean for code you write, and links to the reference page for each. The choices that constrain the whole library, such as dependencies, the browser floor and the security posture, are written down as decision records in the repository.

Table of contents

The library

  • Getting started: install, first template, first component, browser support.
  • Concepts: how the library works and why: rendering, components, fields, failures, styling.

ftl: templating and components

  • Templates: the data-tpl-* command reference.
  • Expressions: the expression language.
  • Web components: the component reference: statics, the two attribute tiers, mappers, the lifecycle, reflection, slots, templates, the registry.
  • Localization: translations, plurals, locale-aware formatters, the built-in message keys.

httpc: the http client

  • Http client: the client and request builders, interceptors, the problems contract.

ful: the component library

  • Getting started: the plugin, a first form, the elements ful ships.
  • Fields and shared protocols: the field model: form association, the claims, the value and change, Enter, validation, the structural tags.
  • Forms: ful-form: the submission pipeline, values, error routing.
  • Inputs: ful-input, ful-checkbox, ful-radio-group.
  • Select: loaders, multiple selection, keyboard, remote data.
  • Files: ful-input-file.
  • Temporal inputs: local dates and times, instants, and the display elements.
  • Tables: ful-table, pagination, sorting, ful-filter-*.
  • Disclosures: tooltips, dialogs, drawers, menus, toasts.
  • Navigation: tabs, accordion, wizard.
  • Async sections: the protocol those four share for filling a section on demand.
  • Timing and storage: debouncing, throttling, and versioned browser storage.
  • Theming: the --ful-* tokens, density, dark mode, icons, structural hooks.

Extending

  • Elements: your own ParsedElement, step by step: declaring, rendering, registering, the internals, waiting, render failures, a worked example.
  • Fields: your own form field: which base, the _build pieces, value and validity, the checklist.
  • Loaders and components: replacing where a select, a table or a form gets its data.

Reference

  • Element reference: every ful-* element's attributes, slots and events, generated from the source.
  • client-errors: the standalone error reporter: the payload it posts, and the endpoint that receives it.
  • Editor support: completion and error reporting in IntelliJ IDEA and VS Code for pages that load fml from a CDN.

The project

Conventions

  • The page author is trusted. Templates, modules, translations and markup are part of the page's source, and raw html is an explicit opt-in through {{{ }}}. The threat model is spelled out in the README.
  • Everything is observable. Fields emit change, forms emit submit/submit:success/submit:failure, pagination emits page:requested, sorters emit sort:requested, disclosures emit section:requested. Field, form, table, pagination, sorter and section events bubble; tabs:change, wizard:change, a dialog's or a drawer's close, dialog:dismiss, drawer:dismiss and activechange do not, so they are listened to on the element that fires them.
  • Everything degrades to the platform. ful-* fields are form-associated custom elements wrapping native controls, the disabled and readonly semantics are the native ones, the dom stays in the light tree, and the styles hook structural tags rather than classes.

Clone this wiki locally