Skip to content

spencerkittleson/dom-builder

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

17 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

@kanmf/dombuilder

Version Documentation Maintenance License: MIT

Lightweight HTML DOM building library with shorthand tags and TypeScript support

Install

npm install @kanmf/dombuilder

Run tests

npm run test

Usage

Basic 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")),
);

Shorthand Tags

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">

Properties

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>

Style

div({ style: { display: "flex", color: "red" } }, "Content");

Dataset

div({ dataset: { userId: 123, isActive: true } });

ARIA Attributes

button({ "aria-label": "Close dialog", role: "button" }, "X");

Custom Attributes

Use the @ prefix for custom attributes:

div({ "@data-custom": "value", "@aria-hidden": "true" });
// <div data-custom="value" aria-hidden="true"></div>

Fragments

import { fragment, div, span } from "@kanmf/dombuilder";

const frag = fragment(div("First"), span("Second"));
// DocumentFragment with two children

SVG

import { 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);

Template Elements

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>

Text Nodes

import { text } from "@kanmf/dombuilder";

const textNode = text("Hello World");
// Text node, not an Element

Style & Slot Elements

For 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" }));

Promises

Pass promises as children - they're resolved and replaced:

const content = div(fetch("/api/data").then((r) => r.text()));
// Text from promise replaces placeholder

Promise 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") }));

TypeScript

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"));

Type Declarations

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", "./"]
  }
}

API Reference

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

Author

🤝 Contributing

Contributions, issues and feature requests are welcome!
Feel free to check issues page.

Show your support

Give a ⭐️ if this project helped you!

📝 License

Copyright © 2026 Spencer Kittleson.
This project is MIT licensed.

About

a html dom building library

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors