The factory is nothing more than an ordinary function, which produces property descriptor. The primary goal of the factories is to hide implementation details and minimize redundant code. Usually, descriptors are similar and have limited differences, which can be parameterized by the function arguments.


Consider an example, where you want to create a property, which updates document.title and holds its original value. Instead of creating a unique descriptor, you can create a re-usable factory:

export default function titleFactory(defaultTitle = '') {
return {
set: (host, value = '') => {
document.title = value;
return value;
connect: (host, key) => {
if (host[key] === undefined) {
host[key] = defaultTitle;

Then, use titleFactory function wherever you want. For example, it is straightforward to refactor <simple-counter> from Getting Started section to make count property connected to the document.title. The only important difference is in the line with the property definition:

import { html, define } from 'hybrids';
import titleFactory from './titleFactory';
export function increaseCount(host) {
host.count += 1;
export const TitleCounter = {
count: titleFactory(0), // definition changed from "count: 0"
render: ({ count }) => html`
<button onclick="${increaseCount}">
Count: ${count}
define('title-counter', SimpleCounter);

Built-in Factories

The hybrids uses factories to provide all the features required for building rich custom elements: