Sklair Logo

HTML deserved better.

Sklair is a compiler that extends HTML with build-time structure, composition, and logic - without changing how the web runs.

What is Sklair?

Sklair is not a framework. It does not replace the DOM, ship a runtime, or redefine how browsers work.

Instead, Sklair operates entirely at build time, extending HTML with components, compiler directives, deterministic optimisation, and sandboxed build hooks.

All of this while producing plain, standard HTML as output.

What Sklair gives you

Compile-time components

Define reusable HTML components that expand deterministically at build time. No runtime cost, no client-side abstraction - just clean output.

Compiler directives

Guide compilation with explicit directives: ordering barriers, removal blocks, and classification hints that give you control without sacrificing automation. Directives are explicit, readable, and intentionally limited - Sklair avoids implicit magic.

Polyglot HTML

Specific directives such as sklair:remove can be used to write HTML that works both as raw HTML and as Sklair input. Useful for previews, isolated component development, and editor tooling.

Deterministic optimisation

Sklair performs predictable, explainable optimisations - especially in <head> ordering and deduplication - without hidden heuristics.

Build-time hooks, safely

Sklair supports pre- and post-build hooks written in sandboxed Lua.

Hooks are ideal for data preparation, asset transformation, and generating build-time artefacts - without introducing runtime complexity.

Sandboxed by design

Hooks run in a restricted environment with a controlled filesystem API - no unrestricted OS access.

Deterministic execution

Hooks run sequentially, without background tasks or concurrency. Builds remain predictable and reproducible.

Data-first workflows

Perfect for compiling structured data into optimised assets that your site can consume directly.

Works with SPAs, too

Sklair does not inherently impose an application model.

Whether you're building a static site, a hybrid app, or a fully client-driven SPA, Sklair prepares your HTML, data, and assets - how you use JavaScript on top is entirely up to you.

Where Sklair is going

Ready to try Sklair?

How Sklair works

Sklair extends HTML at build time. Components expand, directives guide compilation, and the final output is clean, standard HTML - with no runtime abstraction.

The examples below demonstrate how Sklair transforms structure while preserving intent.

Example 1: Basic component expansion

Components are expanded deterministically at build time. The browser never sees component tags — only the final HTML.

Source

src/index.html

<body>
  <SomeHeader></SomeHeader>

  <Content></Content>
</body>

components/SomeHeader.html

<header>
  <h1>Welcome to my site</h1>
</header>

Compiled output

<body>
  <header>
    <h1>Welcome to my site</h1>
  </header>

  <p>...</p>
</body>

Example 2: Components that also contribute to <head>

Components may contain both <head> and <body> content. Sklair merges, deduplicates, and reorders head nodes according to browser loading semantics.

Source

src/index.html

<!DOCTYPE html>
<html>

<head>
    <title>Hello world</title>
</head>

<body>
    <!-- CommonHead is a component which also contributes its own <head> items -->
    <!--
        since components might be repeated, <head> injections are deduplicated
        to ensure that the same items dont get injected multiple times
    -->
    <CommonHead></CommonHead>

    <Content></Content>
</body>

</html>

components/CommonHead.html

<!DOCTYPE html>
<html>

<head>
    <!--
        the order here is purposefully very messed up and unconventional,
        to show an example of sklair fixing this
    -->

    <link href="https://fonts.googleapis.com/css2?family=..." rel="stylesheet">

    <script src="/assets/js/ThemeSync.js" defer></script>

    <!-- sklair:ordering-barrier treat-as=script -->
    <script src="https://cdn.tailwindcss.com"></script>
    <script src="/assets/styles/tailwind.config.js"></script>
    <link rel="stylesheet" href="/assets/styles/global.css">
    <link rel="stylesheet" href="/assets/styles/themes.css">
    <!-- sklair:ordering-barrier-end -->

    <link rel="preconnect" href="https://wcdn.numelon.com">
    <meta charset="UTF-8">
    <meta name="theme-color" content="#ff4e4e">
    <meta name="viewport" content="width=device-width, etc..." />
</head>

<body>
</body>

</html>

Compiled output

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8" />

    <meta name="theme-color" content="#ff4e4e" />
    <meta name="viewport" content="width=device-width, etc..." />

    <link rel="preconnect" href="https://wcdn.numelon.com" />

    <title>Hello world</title>

    <link href="https://fonts.googleapis.com/css2?family=..."
        rel="stylesheet" />
    <script src="/assets/js/ThemeSync.js" defer=""></script>

    <script src="https://cdn.tailwindcss.com"></script>
    <script src="/assets/styles/tailwind.config.js"></script>
    <link rel="stylesheet" href="/assets/styles/global.css" />
    <link rel="stylesheet" href="/assets/styles/themes.css" />

    <meta name="generator" content="https://sklair.numelon.com" />
</head>

<body>
    <p>...</p>
</body>

</html>

Why head ordering matters

The second example above shows how although the <head> of the CommonHead component was unordered and semantically chaotic, the compiled output is deterministically reordered according to browser loading semantics.

This is not a cosmetic change, albeit looking nicer is a plus. Modern browsers stream-parse HTML as the bytes for it arrive, and many <head> elements (such as meta charset, preconnects, stylesheets and scripts) trigger side effects the moment they are encountered. Their relative position therefore directly affects request scheduling, render-blocking, and even URL resolution.

Sklair applies a heuristic head-ordering pass to ensure that these high-impact nodes are discovered as early as possible, improving page load behaviour without requiring authors to manually micromanage this order themselves.

Ordering barriers

In some cases, the relative order of nodes must be preserved. Sklair provides the sklair:ordering-barrier directive to explicitly mark such regions.

<!-- sklair:ordering-barrier treat-as=script -->
<script src="https://cdn.tailwindcss.com"></script>
<script src="/assets/styles/tailwind.config.js"></script>
<!-- sklair:ordering-barrier-end -->

Ordering barriers allow Sklair to optimise aggressively while still respecting intentional sequencing - for example, ensuring that Tailwind configuration scripts load after the Tailwind runtime itself.

Ready to try Sklair?