Skip to main content

h() — Compact Notation

A compact array-based notation for building vnode trees. An alternative to createElement that reads closer to the structure it describes.
import { h } from 'solarbuild'

h(['div', { class: 'card' },
  ['h2', {}, 'Title'],
  ['p', {}, 'Body text'],
])
Equivalent to:
createElement('div', { class: 'card' },
  createElement('h2', {}, 'Title'),
  createElement('p', {}, 'Body text'),
)

Syntax

h([type, props?, ...children])
Each node is an array where:
  • type — a tag name string ('div') or a registered component name ('Button')
  • props — optional object of attributes or props
  • children — remaining items, each a nested array or a primitive
Primitives (strings, numbers) pass through unchanged.

Registry dispatch

If the type matches a registered component name, h() calls that component instead of createElement:
registry.register(Button)

h(['Button', { label: 'Save', onClick: handleSave, variant: 'primary' }])
// equivalent to: Button({ label: 'Save', onClick: handleSave, variant: 'primary' })
Prop validation still runs — a wrong prop type throws a ContractError.

Nested trees

h(['div', { class: 'layout' },
  ['header', {},
    ['h1', {}, 'Solar'],
  ],
  ['main', {},
    ['Button', { label: 'Get started', onClick: () => {}, variant: 'primary' }],
  ],
])

Children on registered components

When h() calls a registered component and there are child nodes, they’re passed as a children prop — not spread as arguments. The component must declare children in its schema to receive them.
const List = defineComponent({
  name: 'List',
  props: {
    children: { type: 'array' },
  },
  render({ children }) {
    return createElement('ul', {}, ...children)
  },
})

h(['List', {},
  ['li', {}, 'Item 1'],
  ['li', {}, 'Item 2'],
])
// children → [vnode, vnode] passed as a prop
For plain DOM elements (div, ul, etc.), children are passed as normal arguments to createElement — no prop involved.

When to use h() vs createElement

h() is more compact and closer to markup in structure. createElement is more explicit and easier to trace in a debugger. Both produce identical vnodes — mix them freely. h() is particularly well-suited as a generation target: the array format is easy for a model to produce without needing to know function call syntax.