Lightweight HTML DOM building library with shorthand tags and TypeScript support
🏠 Homepage
npm install @kanmf/dombuildernpm run testBasic usage is makeElement(type, textOrPropsOrChild, ...otherChildren) or use shorthand functions.
import { div, span, a, makeElement } from "@kanmf/dombuilder";
document.body.appendChild(div());
document.body.appendChild(
makeElement("a", { href: "http://foo.bar" }, span("text")),
);All standard HTML elements have shorthand functions:
import {
a,
button,
div,
p,
span,
ul,
li,
input,
label,
table,
tr,
td,
th,
style,
slot,
} from "@kanmf/dombuilder";
div(); // <div></div>
span("hello"); // <span>hello</span>
button({ disabled: true }, "Click"); // <button disabled>Click</button>
input({ type: "text", placeholder: "Enter text" }); // <input type="text" placeholder="Enter text">Pass an object as the second argument to set properties, attributes, styles, and dataset.
const card = div(
{ className: "card-container" },
a(
{
id: "card-link-foo",
href: "https://foo.bar",
dataset: {
isValid: true,
},
},
"link text",
),
);Result:
<div class="card-container">
<a href="https://foo.bar" id="card-link-foo" data-is-valid="true">
link text
</a>
</div>div({ style: { display: "flex", color: "red" } }, "Content");div({ dataset: { userId: 123, isActive: true } });button({ "aria-label": "Close dialog", role: "button" }, "X");Use the @ prefix for custom attributes:
div({ "@data-custom": "value", "@aria-hidden": "true" });
// <div data-custom="value" aria-hidden="true"></div>import { fragment, div, span } from "@kanmf/dombuilder";
const frag = fragment(div("First"), span("Second"));
// DocumentFragment with two childrenimport { svg } from "@kanmf/dombuilder";
const icon = svg(
'<svg xmlns="http://www.w3.org/2000/svg"><path d="M0 0h24v24H0z"/></svg>',
);Strip <title> element:
const icon = svg(svgString, true);import { template, div, span } from "@kanmf/dombuilder";
const tmpl = template(div({ className: "item" }), span("Text content"));
// <template><div class="item"></div><span>Text content</span></template>import { text } from "@kanmf/dombuilder";
const textNode = text("Hello World");
// Text node, not an ElementFor Shadow DOM:
import { style, slot, div } from "@kanmf/dombuilder";
const shadowRoot = div().attachShadow({ mode: "open" });
shadowRoot.appendChild(style(".foo { color: red; }"));
shadowRoot.appendChild(slot({ name: "header" }));Pass promises as children - they're resolved and replaced:
const content = div(fetch("/api/data").then((r) => r.text()));
// Text from promise replaces placeholderPromise resolving to element:
const content = div(Promise.resolve(span("Loaded")));Promise resolving to object with .element:
const content = div(Promise.resolve({ element: div("From object") }));This library includes TypeScript declarations. Use the Props interface for type safety:
import { div, span, button, Props } from "@kanmf/dombuilder";
const props: Props = {
className: "container",
style: { display: "flex", gap: "10px" },
dataset: { userId: 123 },
"@data-custom": "value",
};
const el = div(props, span("Hello"), button({ disabled: false }, "Click"));If TypeScript shows TS7016: Could not find declaration file, add a reference:
/// <reference path="path/to/declarations.d.ts" />
import { div } from "@kanmf/dombuilder";Or configure tsconfig.json:
{
"compilerOptions": {
"typeRoots": ["./node_modules/@types", "./"]
}
}| Function | Returns | Description |
|---|---|---|
makeElement(type, props?, ...children) |
HTMLElement |
Create any element type |
div(props?, ...children) |
HTMLDivElement |
Shorthand for div |
span(props?, ...children) |
HTMLSpanElement |
Shorthand for span |
a(props?, ...children) |
HTMLAnchorElement |
Shorthand for anchor |
button(props?, ...children) |
HTMLButtonElement |
Shorthand for button |
p(props?, ...children) |
HTMLParagraphElement |
Shorthand for paragraph |
ul(props?, ...children) |
HTMLUListElement |
Shorthand for unordered list |
li(props?, ...children) |
HTMLLIElement |
Shorthand for list item |
input(props?, ...children) |
HTMLInputElement |
Shorthand for input |
label(props?, ...children) |
HTMLLabelElement |
Shorthand for label |
table(props?, ...children) |
HTMLTableElement |
Shorthand for table |
tr(props?, ...children) |
HTMLTableRowElement |
Shorthand for table row |
td(props?, ...children) |
HTMLTableCellElement |
Shorthand for table cell |
th(props?, ...children) |
HTMLTableCellElement |
Shorthand for table header |
style(props?, ...children) |
HTMLStyleElement |
Shorthand for style |
slot(props?, ...children) |
HTMLSlotElement |
Shorthand for slot |
fragment(...children) |
DocumentFragment |
Create document fragment |
svg(svgString, stripTitle?) |
SVGElement |
Parse SVG string |
template(...children) |
HTMLTemplateElement |
Create template element |
text(string) |
Text |
Create text node |
- Github: @aaronmars
- Github: @apatten
- Github: @spencerkittleson
Contributions, issues and feature requests are welcome!
Feel free to check issues page.
Give a ⭐️ if this project helped you!
Copyright © 2026 Spencer Kittleson.
This project is MIT licensed.