Render HTML components with JSX powered by Deno and @fartlabs/jsonx.
Generated API documentation is available at https://jsr.io/@fartlabs/htx.
Let's learn how to get started with HTX by creating a simple example in Deno.
1. Install Deno.
2. Start a new Deno project.
deno init3. Add @fartlabs/htx as a project dependency.
deno add jsr:@fartlabs/htx4. Add the following values to your deno.json(c) file.
{
"compilerOptions": {
"jsx": "react-jsx",
"jsxImportSource": "@fartlabs/htx"
}
}5. Add a file ending in .[j|t]sx to your project. For example, main.tsx.
import { A, BODY, H1, P } from "@fartlabs/htx";
const html = (
<BODY>
<H1>Hello, World!</H1>
<P>This is a paragraph.</P>
<A href="https://jsr.io/@fartlabs/htx">@fartlabs/htx</A>
</BODY>
);
Deno.writeTextFileSync("index.html", html);6. Compile your HTML by running the .[j|t]sx file.
deno run --allow-write main.tsxResulting index.html:
<body>
<h1>Hello, World!</h1>
<p>This is a paragraph.</p>
<a href="https://jsr.io/@fartlabs/htx">@fartlabs/htx</a>
</body>// main.tsx
import { A, BODY, H1, P } from "@fartlabs/htx";
const html = (
<BODY>
<H1>Hello</H1>
<P>
See <A href="https://jsr.io/@fartlabs/htx">@fartlabs/htx</A>
</P>
</BODY>
);
// html is a string
await Deno.writeTextFile("index.html", html);Run:
deno run -A main.tsx// greet.tsx
import { DIV, H1, P } from "@fartlabs/htx";
type GreetProps = { name: string; messages: string[] };
export function Greet(props: GreetProps) {
const { name, messages } = props;
return (
<DIV>
<H1>Hello, {name}!</H1>
{messages.map((m) => <P>{m}</P>).join("")}
</DIV>
);
}
// usage.tsx
import { Greet } from "./greet.tsx";
const page = <Greet name="Ada" messages={["Welcome", "Enjoy your stay"]} />;
console.log(page); // stringimport { BODY, H1, P } from "@fartlabs/htx";
Deno.serve((_req) => {
const body = (
<BODY>
<H1>HTX Server</H1>
<P>Rendered via JSX and returned as text/html.</P>
</BODY>
);
return new Response(
body,
{ headers: { "content-type": "text/html; charset=utf-8" } },
);
});Run:
deno run --allow-net server.ts- @fartlabs/ht — minimal HTML tag helpers for Deno/TypeScript
- @fartlabs/jsonx — JSX runtime for string-first rendering
For the canonical best practices, see the HTX guide:
- HTX concepts and best practices: https://jsonx.fart.tools/concepts/htx
The following table contrasts HTX with React, reflecting the Mental model and Benefits discussed in the guide linked above.
| HTX | React |
|---|---|
| String generation; concatenate HTML | Virtual DOM diff and reconciliation |
| HTML string | React elements that render to DOM |
Direct DOM APIs (e.g., insertAdjacentHTML) |
setState/useState with reconciliation |
Map and .join("") |
Map elements; no manual join |
| Ternary to empty string | Logical AND or ternary returning elements |
| Functions returning strings | Components returning elements |
| Minimal; no VDOM | VDOM runtime, scheduler |
| First-class — strings are source of truth | DOM/element tree is source of truth |
| What you write is what gets rendered | Abstractions can obscure output |
| Inspect exact HTML strings | Requires inspecting component tree/DOM |
| No VDOM overhead | VDOM diffing/reconciliation cost |
| No complex state or reconciliation | State and lifecycle management required |
- See Versions for version history.
Run deno fmt to format the code.
Run deno lint to lint the code.
Run deno task generate to generate the code.
Run the test suite with Deno:
deno test -A- If JSX fails to compile, ensure your
deno.json(c)has:
{
"compilerOptions": {
"jsx": "react-jsx",
"jsxImportSource": "@fartlabs/htx"
}
}This project is licensed under the WTFPL. See LICENSE for details.
Developed with ❤️ @FartLabs