Docs
/
API
/
Basics
/
m()

m()

Syntax: m(tag, props?, children?, flag?, delta?)
Example: m('div', { id: 'app' }, ['Hello World'])

It is recommended that you use m to create a VNode. It accepts a tag as a string, an optional props object, an optional array of children, and an optional flag.

import { m } from 'million';

const vnode = m('div', { id: 'app' }, ['Hello World']);
{
  tag: 'div',
  props: {
    id: 'app'
  },
  children: ['Hello World'],
}

The tagName is stored under the tag, attributes and properties are stored under props, and the children are stored under children.

REPL

You can enter HTML and it will automatically convert to a VNode if you are confused on how the raw data representation looks.

Optimization via keys

Most of the time, the diffing and patching process is fast enough, but when dealing with a large amount of children, it is best to provide runtime hints through keys. You can attach a key under props. When patched, it will only diff props and children if the key is changed. For more advanced runtime diffing using keys, check out Flags.ELEMENT_KEYED_CHILDREN.

import { m } from 'million';

const vnode = m('div', { key: 'foo' }, ['Hello World']);
{
  tag: 'div',
  props: {},
  children: ['Hello World'],
  key: 'foo',
}

className and style props helpers

The className and style props need to be preprocessed using the className and style functions to convert objects to strings. The class object syntax allows for you to toggle classes based on a boolean value. The style object syntax allows you to set styles in a clean format.

import { m, className, style } from 'million';

const vnode = m(
  'div',
  {
    className: className({ class1: true, class2: false, class3: 1 + 1 === 2 }),
    style: style({ color: 'black', 'font-weight': 'bold' }),
  },
  ['Hello World'],
);
{
  tag: 'div',
  props: {
    className: 'class1 class3',
    style: 'color:black;font-weight:bold'
  },
  children: ['Hello World'],
}

kebab props helper

Generally, the values of className and style props are objects in kebab-case. However, if you want to use camelCase for the keys of these props, you can use the kebab function to convert the keys from camelCase to kebab-case.

import { m, style, kebab } from 'million';

const vnode = style(kebab({ color: 'black', fontWeight: 'bold' }));
{
  tag: 'div',
  props: {
    style: 'color:black;font-weight:bold'
  },
  children: ['Hello World'],
}

SVG support

SVGs are handled by default, but sometimes you need to attach SVG namespaces. SVGs are processed using the svg function to add ns props to the element and all of the children of that element.

import { m, svg } from 'million';

const vnode = svg(m('svg'));
{
  tag: 'svg',
  props: {
    ns: 'http://www.w3.org/2000/svg'
  },
}

toVNode SSR helper

The toVNode function converts an HTMLElement or Text or HTML string to a VNode. This is generally used to rehydrate HTML from SSR.

import { m, toVNode, patch } from 'million';

// HTML string
const vnode1 = toVNode('<div>Hello World</div>'); // holds <div>Hello World</div> in VNode form

// HTMLElement
const el = document.createElement('div');
el.textContent = 'Hello World';
const vnode2 = toVNode(el); // holds <div>Hello World</div> in VNode form
<div id="app">Hello World</div>