Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

simple-html-tag

acorcutt45Unlicense2.0.0TypeScript support: included

A simple and fast tag function for safe html es6 literals.

es6, tag, literal, html, safe

readme

simple-html-tag

A simple, fast, and secure tagged template literal function for creating HTML strings with automatic XSS protection.

import { html } from "simple-html-tag";

const name = "World";
const greeting = html`Hello ${name}`;
console.log(greeting); // "Hello World"

Features

Zero dependencies - Lightweight and fast
🔒 XSS protection - Automatic HTML escaping by default
🚀 TypeScript support - Full type safety and IntelliSense
High performance - Optimized for speed with pre-compiled regexes
🔄 Async support - Handle promises and async data seamlessly
📦 ESM/CommonJS - Works with modern bundlers and Node.js

Installation

npm install simple-html-tag
yarn add simple-html-tag
pnpm add simple-html-tag
bun add simple-html-tag

Quick Start

import { html, safe } from "simple-html-tag";

// Automatic XSS protection
const userInput = '<script>alert("xss")</script>';
const result = html`<div>Hello ${userInput}</div>`;
console.log(result); // <div>Hello &lt;script&gt;alert("xss")&lt;/script&gt;</div>

// Safe HTML when you trust the content
const trustedHtml = safe("<strong>Bold text</strong>");
const result2 = html`<div>${trustedHtml}</div>`;
console.log(result2); // <div><strong>Bold text</strong></div>

API Reference

html - Tagged Template Literal

Creates HTML strings with automatic escaping of interpolated values.

import { html } from "simple-html-tag";

const name = '<script>alert("xss")</script>';
const age = 25;

const result = html`
  <div class="user">
    <h1>Hello ${name}</h1>
    <p>Age: ${age}</p>
  </div>
`;
// All variables are automatically escaped except those marked as safe

safe - Mark Content as Safe

Marks a string as safe HTML that should not be escaped.

import { html, safe } from "simple-html-tag";

const trustedContent = safe("<em>This will not be escaped</em>");
const userContent = "<script>This will be escaped</script>";

const result = html`
  <article>
    ${trustedContent}
    <p>${userContent}</p>
  </article>
`;

htmlAsync - Async Template Literal

Handles promises and async data in template literals.

import { htmlAsync, safe } from "simple-html-tag";

async function renderUser(userId) {
  const user = await fetchUser(userId);
  const avatar = await fetchAvatar(userId);

  return htmlAsync`
    <div class="user">
      <img src="${avatar.url}" alt="${user.name}">
      <h1>${user.name}</h1>
      <p>${user.bio}</p>
    </div>
  `;
}

Usage Examples

Basic HTML Generation

import { html } from "simple-html-tag";

function createButton(text, type = "button") {
  return html`<button type="${type}" class="btn">${text}</button>`;
}

const submitBtn = createButton("Submit", "submit");

Working with Arrays

import { html } from "simple-html-tag";

const items = ["Apple", "Banana", "Cherry"];

const list = html`
  <ul>
    ${items.map((item) => html`<li>${item}</li>`)}
  </ul>
`;

Components with Safe HTML

import { html, safe } from "simple-html-tag";

function userCard(user) {
  const avatar = user.avatar ? html`<img src="${user.avatar}" alt="${user.name}" />` : safe('<div class="avatar-placeholder"></div>');

  return html`
    <div class="user-card">
      <div class="avatar">${avatar}</div>
      <h3>${user.name}</h3>
      <p>${user.email}</p>
    </div>
  `;
}

Async Data Loading

import { htmlAsync } from "simple-html-tag";

async function renderArticle(articleId) {
  const article = fetchArticle(articleId);
  const author = fetchAuthor(articleId);

  return htmlAsync`
    <article>
      <h1>${article.title}</h1>
      <p>By ${author.name}</p>
      <div>${article.content}</div>
    </article>
  `;
}

Security

This library automatically escapes all interpolated values to prevent XSS attacks:

  • & becomes &amp;
  • < becomes &lt;
  • > becomes &gt;
  • " becomes &quot;
  • ' becomes &#x27;
  • / becomes &#x2F;

Only content explicitly marked with safe() will bypass escaping.

Performance

  • Pre-compiled regular expressions for fast escaping
  • Minimal object creation and string concatenation
  • Optimized for template literal performance
  • Zero dependencies for maximum efficiency

TypeScript

Full TypeScript support with comprehensive type definitions:

import { html, safe, htmlAsync } from "simple-html-tag";

// Type-safe HTML generation
const result: string = html`<div>${"text"}</div>`;

// Safe HTML is properly typed
const safeHtml: string & { [Symbol]: true } = safe("<b>bold</b>");

// Async version returns Promise<string>
const asyncResult: Promise<string> = htmlAsync`<div>${Promise.resolve("text")}</div>`;

Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Development

# Install dependencies
bun install

# Run tests
bun test

# Build package
bun run build

# Watch mode for tests
bun run watch

License

This project is licensed under the Unlicense - see the LICENSE file for details.

Credits

Created by Anthony Corcutt
Documented and enhanced by GitHub Copilot