el()
The el() function creates element specs — blueprints for DOM elements with reactive props and children.
Syntax
Section titled “Syntax”el(tag)el(tag).props(props)el(tag).props(props).ref(...callbacks)el(tag)(children)el(tag).props(props)(children)Parameters
Section titled “Parameters”tag
: The element tag name. For the DOM adapter, this is any valid HTML tag ('div', 'button', 'input', etc.).
props (optional)
: An object of attributes, properties, and event handlers. Values can be static or reactive.
callbacks (optional)
: Lifecycle callbacks passed to .ref(). Called with the element when created, return a cleanup function for disposal.
children (optional)
: Child content — strings, numbers, reactive values, or other element specs.
Return value
Section titled “Return value”An ElementSpec for use with mount() or as a child of other elements.
Description
Section titled “Description”el() is curried and chainable:
// Just a tagel('div')
// With propsel('div').props({ className: 'container' })
// With childrenel('div')('Hello')
// Full chainel('button') .props({ onclick: handleClick }) .ref(callback) ('Click me')Stable elements
Section titled “Stable elements”Elements are created once. Only individual props and text nodes update when their reactive values change:
const count = signal(0);
// This element is created once// Only the text "Count: X" updates when count changesconst display = el('div')( computed(() => `Count: ${count()}`));Reactive props
Section titled “Reactive props”Props can be static values or reactive (signals/computeds):
const isDisabled = signal(false);const label = computed(() => isDisabled() ? 'Disabled' : 'Click me');
el('button').props({ className: 'btn', // static disabled: isDisabled, // reactive onclick: () => doSomething() // event handler})(label) // reactive childChildren
Section titled “Children”The final call accepts any number of children:
el('div')( 'Text content', el('span')('Nested element'), computed(() => `Dynamic: ${value()}`), someCondition && el('p')('Conditional'))Children can be:
- Strings and numbers (rendered as text)
- Reactive values (signals, computeds)
- Other element specs
nullorundefined(ignored)- Arrays of any of the above
Examples
Section titled “Examples”Basic elements
Section titled “Basic elements”// Empty divel('div')()
// Div with textel('div')('Hello, world')
// Nested structureel('article')( el('h1')('Title'), el('p')('First paragraph'), el('p')('Second paragraph'))With props
Section titled “With props”el('input').props({ type: 'text', placeholder: 'Enter name...', value: name, oninput: (e) => name(e.target.value)})()
el('a').props({ href: 'https://example.com', target: '_blank'})('Visit site')Reactive updates
Section titled “Reactive updates”const theme = signal<'light' | 'dark'>('light');const count = signal(0);
el('div').props({ className: computed(() => `app theme-${theme()}`),})( el('p')(computed(() => `Count: ${count()}`)), el('button').props({ onclick: () => count(count() + 1) })('Increment'))With ref callbacks
Section titled “With ref callbacks”el('input') .props({ type: 'text' }) .ref( (input) => input.focus(), (input) => { // Setup const handler = () => console.log('focused'); input.addEventListener('focus', handler); // Cleanup return () => input.removeEventListener('focus', handler); } )()Partial application
Section titled “Partial application”Pre-bind commonly used tags:
const div = el('div');const button = el('button');const input = el('input');
// Use without repeating tag namesdiv.props({ className: 'container' })( input.props({ type: 'text' })(), button.props({ type: 'submit' })('Submit'))See also
Section titled “See also”- map() — Render lists of elements
- match() — Conditional element rendering
- mount() — Attach element specs to the DOM
- Adding a UI — Tutorial on building UIs