What is Heximal?

Heximal enhances HTML to be more dynamic, interactive, and composable. It's like HTML from the future, designed to make building rich, data-driven documents and applications easier than ever.

Heximal is standards-based and works seamlessly with modern HTML. It runs anywhere HTML does, with no build step required.

Why Heximal?

While HTML is already dynamic, much of that dynamism requires JavaScript and the DOM APIs to unlock. HTML has been gaining some great declarative interaction features like invoker commands, but a vast number of common interaction patterns require writing script. Heximal makes HTML more declaratively dynamic, similar to modern client-side web frameworks.

Many projects have also attempted to make HTML more declaratively dynamic, but they tend to work by adding special, relatively high-level, attributes. Heximal is taking a different approach of defining new composable primitives: reactive state, templates, data binding, expressions, and component definitions.

The goal is to enable a very flexible and powerful system that enables the same kind of use cases, and much more, by combining those primitives in many different ways.

Heximal tries to solve many common use cases and feature requests against HTML elegantly with these primitives, such as:

Heximal's philosophy is to utilize the web platform as much as possible. Heximal's extensions are coherent with and extend the platform APIs, making them available from markup. Component are just web components; templates use the <template> tag; events are native Events; etc.

By defining features this way, Heximal hopes to inform upcoming HTML and DOM standards. Ideally, Heximal is made obsolete by future versions of the web platform.

Features at a Glance

Declarative State: Variables, Outputs, and Scopes

Heximal starts with a way to define reactive state in markup. This state can then be accessed from all the other features like outputs, and expressions in templates, and components. Because the state is backed by Signals, when the state updates the use-sites update too.

Variables

Add variables to HTML with the <h-var> element:

<h-var name="name" value="World"></h-var>

These variables can then be referenced in expressions.

Outputs

The <h-out> element renders expressions to the document:

<h1>Hello <h-out expr="name"></h-out></h1>

Scopes

Variables are lexically scoped. New scopes can be defined with <h-scope>:

<h-var name="name" value="World"></h-var>

<h-scope>
  <h-var name="name" value="Heximal"></h-var>
  <p>
    <!-- Here `name` is 'Heximal' -->
    Inner name is: <h-out expr="name"></h-out>
  </p>
</h-scope>

<p>
  <!-- Here `name` is 'World' -->
  Outer name is: <h-out expr="name"></h-out>
</p>

In addition to variables declared in the document, scopes have access to window, `document, and a couple of Heximal-specific properties:

Reactivity

Variables are backed by signals, so when they change, the document automatically updates:

<h-var name="name" value="World"></h-var>
<h1>Hello <h-out expr="name"></h-out></h1>

<template h-auto>
  <button @click="{{ () => name = 'Heximal' }}">Set Name</button>
</template>

In this example, when the button is clicked document will display <h1>Hello Heximal</h1>. See the next section for information on templates and bindings.

Templates

Heximal Templates enhance the HTML <template> element with bindings, expressions, and control flow like if and repeat.

<template id="my-template">
  <h2>Messages</h2>

  <template type="if" if="{{ important }}">
    <p class="important">These messages are important</p>
  </template>

  <template type="repeat" repeat="{{ messages }}">
    <p>{{ item.text }}</p>
  </template>
</template>

Templates can be used as a part of custom elements, standalone, or as auto templates that automatically render to the document.

Bindings

Heximal templates support data binding with expressions marked by the separators {{ ... }}.

Auto-templates

Auto templates let you use template binding syntax and control flow anywhere in your page. They are <template> elements that are immediately rendered in-place without being part of a component or called from another template.

Auto templates are declared with the h-auto attribute.

<body>
  <template h-auto>
    <h1>Hello {{ name }}</h1>
  </template>
</body>

Components

HTML already has components - web components - so Heximal doesn't need to add them. You can import existing components, say from npm via a CDN like jsdelivr.com. You can also write your own web components in script using the web APIs directly, or with a helper library like Lit (which Heximal uses internally).

Once you have a component, you can use it in your document, and bind to it within Heximal templates:

<cool-component .someProp="{{ data.foo }}"></cool-component>

What Heximal adds to this is the ability to define new reusable or web components declaratively, right in HTML, with the <h-define-element> element.

<h-define-element name="simple-greeter">
  <h-prop name="name"></h-prop>

  <style type="adopted-css">
    :host {
      color: blue;
    }
  </style>

  <template>
    <h1>Hello {{ name }}!</h1>
  </template>
</h-define-element>

These elements can then be used anywhere in the HTML document.

<simple-greeter name="World"></simple-greeter>

Built-in Heximal Elements

Utilities

Display

Project Status

Heximal is a work in progress. It is insecure, unstable, and will have frequent breaking changes. Please use accordingly.

🀝 Seeking Collaborators!

The best way to help Heximal reach a stable release is to get involved. If you like the Heximal vision, please drop by the Heximal GitHub repo and file issues or submit PRs.

⚠️ Security

Because of Heximal expressions use a custom evaluator, they allow writing code in markup that is not controlled by Content Security Policy (CSP). This makes using Heximal in any context with user-generated or user-controlled content currently extremely unsafe. Sanitizers must be configured to only allow safe tags, not disallow tags, since Heximal introduces new script-like tags like <h-out>, h-define-element>, <template h-auto>, etc.

It is possible to make Heximal secure. Work is planned to address security issues, such as expression-aware HTML sanitizers, safer expression evaluation, disallowing "gadgets" by default, supporting nonces on script-like elements, and new standards proposals. Please follow the Security issue for more information and updates.

πŸ—ΊοΈ Roadmap

Some of the planned improvements and additions to Heximal include:

Get Started

Install Heximal via npm:

npm install heximal

Import it into your page:

<script type="module" src="/path/to/node_modules/heximal/index.js"></script>

The GitHub repo has somewhat more detailed information until full documentation is available.

Relevant Standards Proposals

Heximal is in part an effort to prototype and inform several web standards proposals, including:

Inspirations