hypra

Pages that compile.

Hypra is a markup language with a compiler. One file becomes accessible HTML for browsers, Markdown for AI agents and typed tools for anything that acts on your site. A page with a mistake doesn't build, so nobody sees it.

v0.1.0 · Rust · MIT or Apache-2.0

product.hyprathe source
page(title: "Runner X", description: "A light running shoe for long distances, with free returns.") {
  props(product: Product)
  h1 "{product.name}"
  img(product.photo, alt: "{product.name}, side view")
  p "{product.summary}"
  action("cart.add", id: product.id) "Add to cart"
}

01One file, every output

What the compiler made from the file above and one product from the database. Nothing is written twice, and every output is checked.

HTMLfor browsers
<h1>Runner X</h1>
<img src="/img/runner-x.jpg" alt="Runner X, side view" loading="lazy">
<p>220 g, made for long distances.</p>
<form method="post" action="/_a/cart.add" toolname="cart.add" tooldescription="Add to cart">
  <input type="hidden" name="id" value="42">
  <button type="submit">Add to cart</button>
</form>
Markdownfor AI agents
---
title: "Runner X"
description: "A light running shoe for long distances, with free returns."
---

# Runner X

![Runner X, side view](/img/runner-x.jpg)

220 g, made for long distances.

[Action: Add to cart]

## Actions

- `cart.add(id: 42)`: Add to cart → POST /_a/cart.add
Toolsfor agents that act
[
  {
    "name": "cart.add",
    "description": "Add to cart",
    "inputSchema": {
      "type": "object",
      "properties": {
        "id": {
          "type": "integer",
          "const": 42
        }
      },
      "required": [
        "id"
      ]
    }
  }
]

02Mistakes stop at the compiler

A missing description, an image without alt text, a typo in an element: Hypra says where, why and how to fix it, in words a person and an AI that writes the page both understand.

hypra check broken.hypra3 errors
error[SEO-001]: `page` needs `description`
 --> broken.hypra:1:1
  |
1 | page(title: "Shoes") {
  | ^^^^
  = help: add description: "..." (search results and link previews use it), here or in the layout

error[A11Y-001]: image has no alt text
 --> broken.hypra:3:7
  |
3 |   img("/shoe.jpg")
  |       ^^^^^^^^^^^
  = help: add alt: "..." or decorative: true

error[SEM-001]: unknown element `buton`
 --> broken.hypra:4:3
  |
4 |   buton "Buy"
  |   ^^^^^
  = help: did you mean `button`?

3 errors, 0 warnings

03What you get

Accessible by default
Alt text, labels, heading order, link text and captions are checked, not hoped for.
SEO without plugins
Title, description, canonical, Open Graph and Twitter tags come from the page's settings.
Safe with any data
Data is always text: no cross-site scripting, no fake Markdown for agents, no CSRF token sent to another site.
Works with your stack
Tailwind, Alpine.js, htmx and web components work as they are.
Ready for Laravel
.hypra files are views, and one URL answers in HTML, Markdown or JSON.
One small binary
Under a megabyte, written in Rust. Pages compile in milliseconds.

04Guides

05Install

Command line

With Rust, or download a build for Linux, macOS or Windows.

cargo install hypra

Laravel

Downloads the compiler for you, no Rust needed. Laravel docs

composer require hypra/laravel
php artisan hypra:install

VS Code and Cursor

Errors as you type, go to definition, rename, hover help. Extension docs

# Cursor, VSCodium and other editors that install from Open VSX
cursor --install-extension hypralang.hypra
# VS Code: the extension from the release
curl -LO https://github.com/hypralang/hypra/releases/download/v0.1.0/hypra-0.1.0.vsix
code --install-extension hypra-0.1.0.vsix