Skip to content

Instantly share code, notes, and snippets.

@MarekZeman91
Last active November 13, 2025 14:54
Show Gist options
  • Select an option

  • Save MarekZeman91/b74d31eda1001f8380109ab5c1606108 to your computer and use it in GitHub Desktop.

Select an option

Save MarekZeman91/b74d31eda1001f8380109ab5c1606108 to your computer and use it in GitHub Desktop.
One of the laziest EL implementations, but with cache
export function el<K extends keyof HTMLElementTagNameMap>(
nodeName: K,
props?: Record<string, unknown>,
children?: (string | number | boolean | Node)[],
): HTMLElementTagNameMap[K];
export function el<T extends HTMLElement>(
nodeName: string,
props?: Record<string, unknown>,
children?: (string | number | boolean | Node)[],
): T;
export function el(
nodeName: string,
props: Record<string, unknown> = {},
children: (string | number | boolean | Node)[] = [],
): HTMLElement {
const {
class: className,
style = {},
data = {},
dataset = {},
...rest
} = props;
const classes = [className ?? '', rest.className ?? ''].join(' ').trim();
const element = (
el.cache[nodeName] ||
(el.cache[nodeName] = document.createElement(nodeName))
).cloneNode(false) as HTMLElement;
classes && (element.className = classes);
Object.assign(element.style, style);
Object.assign(element.dataset, data, dataset);
for (const [key, value] of Object.entries(rest)) {
if (key.startsWith('on') && typeof value === 'function') {
element.addEventListener(
key.slice(2).toLowerCase() as never,
value as never,
);
} else if (key in element) {
element[key as never] = value as never;
} else {
element.setAttribute(key, String(value));
}
}
element.append(...(children as (Node | string)[]));
return element;
}
el.cache = {} as Record<string, HTMLElement>;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment