YAHTML (YAML HTML) lets you write HTML as valid YAML. It's more concise than HTML while maintaining full expressiveness. Since it's valid YAML, you get structured data that can be parsed as YAML/JSON.
YAHTML - Clean and concise:
- div#home:
- div.header:
- h2.title: "Welcome"
- div.body:
- p.text: "Hello World!"Traditional HTML - More verbose:
<div id="home">
<div class="header">
<h2 class="title">Welcome</h2>
</div>
<div class="body">
<p class="text">Hello World!</p>
</div>
</div>HTML, while powerful and ubiquitous, has several pain points that YAHTML addresses:
1. Visual Noise HTML's angle brackets, closing tags, and attribute syntax create visual clutter that obscures the actual content structure.
2. Redundancy Every opening tag requires a corresponding closing tag, doubling the markup for structure:
<div>requires</div><section>requires</section>- Nested structures multiply this redundancy
3. Poor Structure Visibility In complex HTML documents, it's difficult to see the hierarchical structure at a glance. Indentation helps but isn't enforced, and closing tags add noise.
YAHTML leverages YAML's natural strengths to create a more elegant markup language:
1. Structure Through Indentation The hierarchy is immediately visible through enforced indentation.
2. Extreme Conciseness
- No closing tags needed
- Minimal syntax for attributes
- ID and class notation with dots (
div#home.card.active)
3. Less Visual Noise By removing angle brackets and closing tags, the content and structure become the focus:
# YAHTML
- nav.primary-nav:
- a href="/home": "Home"
- a href="/about": "About"vs
<!-- HTML -->
<nav class="primary-nav">
<a href="/home">Home</a>
<a href="/about">About</a>
</nav>- 100% Valid YAML: Every YAHTML document is syntactically valid YAML
- HTML Complete: Can express any HTML structure or element
- Syntactic Conveniences: Streamlined notation for IDs (#), classes (.), and optional quotes for single-word attributes
YAHTML makes conscious trade-offs:
Limitations:
- Line Length: Complex elements with many attributes can create long lines
- 'div class="card featured" id="main-card" data-category="premium" style="transform: rotate(45deg); position: relative;"': "Content"
If you have a lot of long attributes and attribute values, YAHTML will lose its benefits.
In YAHTML, everything is always an array, starting from the root. This consistent structure ensures predictable parsing and allows any element to have children.
- element-declaration
- element-declaration
# ...The only exception is the leaf nodes (final content). If an element's value is not an array, it cannot have children:
- div: # Array value - can have children
- p: "Hello" # String value - cannot have children
- div: # Array value - can have children
- span: "World" # String value - cannot have children- h1: "Page Title"
- p: "Some text content"
- br: # Self-closing element- div.card:
- h2: "Card Title"
- p: "Card description goes here."
- button: "Learn More"Use # to add IDs and . to add classes to elements:
- button#submit-btn: "Submit"
- div.card.featured: "Featured content"This creates:
<button id="submit-btn">Submit</button>
<div class="card featured">Featured content</div>The notation:
button.primary→<button class="primary">button.primary.large→<button class="primary large">div#main.container.fluid→<div id="main" class="container fluid">
YAHTML uses standard HTML attributes. Quotes are optional for attribute values without spaces:
- div class=container id=main: # No quotes needed for single words
- div class="container fluid": # Quotes required for values with spaces
- img src=photo.jpg alt="A photo":
- input type=email name=user-email required:
- a href=https://example.com target=_blank: "External Link"The style attribute works like any other standard HTML attribute:
- 'div style="width: 300px; height: 200px; background-color: #f0f0f0;"':
- 'p style="color: red; font-size: 18px;"': "Styled text"
- 'div style="transform: translate(10px, 20px); opacity: 0.8;"':Use { __html: '...' } to insert pre-rendered HTML without escaping:
- div:
__html: '<b>bold</b> and <em>italic</em>'This outputs:
<div><b>bold</b> and <em>italic</em></div>Useful for inserting pre-rendered content like Markdown output or sanitized user HTML. Ensure the content is trusted/sanitized before using.
Use consistent 2-space indentation throughout the document to keep it concise.
Note: Prettier formatter will always uses 4-space indentation for YAML arrays
The main difference is that a YAHTML document is 100% valid YAML, allowing it to leverage existing YAML tooling and integrate seamlessly with YAML or JSON based configurations.
You can use YAHTML with Jempl, which will give you the full power of a templating engine while maintaining the universal YAML/JSON structure.
npm install yahtmlOr with Bun:
bun add yahtmlimport { convertToHtml } from 'yahtml';
const yahtmlContent = [
{
'div#app.container': [
'h1: "My Page"',
'p: "Welcome to YAHTML!"',
'button.primary: "Click me"'
]
}
];
const html = convertToHtml(yahtmlContent);
console.log(html);
// Output: <div id="app" class="container"><h1>My Page</h1><p>Welcome to YAHTML!</p><button class="primary">Click me</button></div>Converts a YAHTML array to an HTML string.
Parameters:
yahtmlContent(Array): The YAHTML content as an array
Returns:
- (string): The converted HTML string
Throws:
TypeError: If yahtmlContent is not an arrayError: If element structure is malformed