Improve root README.md with comprehensive monorepo documentation
Based on a thorough review of the entire repository, here is what an optimal root README.md would look like for FartLabs/ht:
FartLabs/ht




A monorepo hosting two complementary, type-safe HTML rendering packages for Deno and TypeScript:
| Package |
Description |
Style |
@fartlabs/ht |
Type-safe HTML string rendering — no JSX required |
Lowercase functions: div({}, "hello") |
@fartlabs/htx |
JSX rendering powered by @fartlabs/jsonx |
Uppercase JSX components: <DIV>hello</DIV> |
Both packages cover HTML, SVG, and MathML elements. Typings are auto-generated from @mdn/browser-compat-data, including deprecated/experimental markers. All element functions return plain HTML strings — no virtual DOM, no runtime overhead.
Packages
@fartlabs/ht — Plain TypeScript
Type-safe, zero-runtime-dependency HTML string builder. Each HTML/SVG/MathML element is a TypeScript function that accepts typed props and optional string children and returns a string.
Install:
deno add jsr:@fartlabs/ht
Quick start:
import { a, div, h1, p } from "@fartlabs/ht";
const page = div(
{ id: "app" },
h1({}, "Hello"),
p({}, "See ", a({ href: "https://jsr.io/@fartlabs/ht" }, "@fartlabs/ht")),
);
// <div id="app"><h1>Hello</h1><p>See <a href="...">@fartlabs/ht</a></p></div>
SVG example:
import { circle, svg } from "@fartlabs/ht/svg";
const icon = svg(
{ width: "100", height: "100" },
circle({ cx: "50", cy: "50", r: "40", fill: "yellow" }),
);
MathML example:
import { math, mi, mo, msup } from "@fartlabs/ht/mathml";
const formula = math({}, msup({}, mi({}, "x"), mi({}, "2")), mo({}, "+"), mi({}, "y"));
// <math><msup><mi>x</mi><mi>2</mi></msup><mo>+</mo><mi>y</mi></math>
Full docs → packages/ht/README.md and https://jsr.io/@fartlabs/ht
@fartlabs/htx — JSX
Write JSX that renders directly to HTML strings. Components are the UPPERCASE versions of HTML tag names (e.g. DIV, H1, INPUT). Powered by @fartlabs/jsonx.
Install:
deno add jsr:@fartlabs/htx
Configure JSX in deno.json:
{
"compilerOptions": {
"jsx": "react-jsx",
"jsxImportSource": "@fartlabs/htx"
}
}
Quick start (main.tsx):
import { A, BODY, H1, P } from "@fartlabs/htx";
const html = (
<BODY>
<H1>Hello, World!</H1>
<P>See <A href="https://jsr.io/@fartlabs/htx">@fartlabs/htx</A></P>
</BODY>
);
Deno.writeTextFileSync("index.html", html);
Custom components:
import { DIV, H1, P } from "@fartlabs/htx";
type GreetProps = { name: string; messages: string[] };
function Greet({ name, messages }: GreetProps) {
return (
<DIV>
<H1>Hello, {name}!</H1>
{messages.map((m) => <P>{m}</P>).join("")}
</DIV>
);
}
Full docs → packages/htx/README.md and https://jsr.io/@fartlabs/htx
Repository structure
FartLabs/ht/
├── generate.ts # Centralized code generation script for both packages
├── packages/
│ ├── ht/ # @fartlabs/ht — plain TypeScript API
│ │ ├── deno.json
│ │ ├── README.md
│ │ └── src/
│ │ ├── render.ts # renderElement, renderAttrs, renderStyle
│ │ ├── global_attributes.ts # GlobalAttributes, DataAttributes (generated)
│ │ ├── mod.ts / html.ts / svg.ts / mathml.ts (generated)
│ │ └── elements/html|svg|mathml/ (generated per-element files)
│ └── htx/ # @fartlabs/htx — JSX API
│ ├── deno.json
│ ├── README.md
│ └── src/
│ ├── render.ts # Re-exports @fartlabs/ht/render
│ ├── jsx-runtime.ts # Re-exports @fartlabs/jsonx/jsx-runtime
│ ├── global_attributes.ts (generated, adds children prop)
│ ├── mod.ts / html.ts / svg.ts / mathml.ts (generated)
│ └── elements/html|svg|mathml/ (generated per-element files)
└── .github/workflows/
└── weekly.yaml # Auto-update BCD, regenerate, bump patch versions
Key differences between @fartlabs/ht and @fartlabs/htx
|
@fartlabs/ht |
@fartlabs/htx |
| API style |
div({class:"x"}, "child") |
<DIV class="x">child</DIV> |
| Function naming |
lowercase (a, div, h1) |
UPPERCASE (A, DIV, H1) |
| Children |
Rest parameters ...children: string[] |
children prop or rest parameters |
| JSX runtime |
None |
@fartlabs/jsonx |
| Props type imports |
Re-exported from own package |
Imported from @fartlabs/ht |
Code generation
All files under packages/*/src/elements/ and packages/*/src/global_attributes.ts are auto-generated. Do not edit them directly.
To regenerate both packages from the latest MDN Browser Compatibility Data:
A weekly CI job (.github/workflows/weekly.yaml) automatically updates the @mdn/browser-compat-data dependency, regenerates both packages, runs tests, and bumps the patch version of both packages/ht/deno.json and packages/htx/deno.json when data changes.
Contributing
deno fmt # Format code
deno lint # Lint code
deno test # Run tests
deno task generate # Regenerate element files from MDN BCD
If you change generation logic in generate.ts, run deno task generate and commit the resulting file changes.
See individual package READMEs for package-specific notes:
License
@fartlabs/ht — MIT License
@fartlabs/htx — WTFPL
Developed with ❤️ @FartLabs
Notes
-
The repository has no root deno.json visible in the file tree (only deno.lock and generate.ts at root), so the root README is purely documentation — it does not serve as a Deno workspace config. A root deno.json would be the natural companion if workspace support were added.
-
The generate.ts file is the single source of truth for both packages. Any changes to element generation must go through it.
-
@fartlabs/htx does not have its own JSX runtime implementation — it delegates entirely to @fartlabs/jsonx via re-export in jsx-runtime.ts.
-
The @fartlabs/htx package has a separate README (packages/htx/README.md) that still references the old @fartlabs/htx JSR badge URL and GitHub Actions URL from the original standalone repo — these should be updated to point to the monorepo URLs once the root README exists.
Improve root README.md with comprehensive monorepo documentation
Based on a thorough review of the entire repository, here is what an optimal root
README.mdwould look like forFartLabs/ht:FartLabs/ht
A monorepo hosting two complementary, type-safe HTML rendering packages for Deno and TypeScript:
@fartlabs/htdiv({}, "hello")@fartlabs/htx@fartlabs/jsonx<DIV>hello</DIV>Both packages cover HTML, SVG, and MathML elements. Typings are auto-generated from
@mdn/browser-compat-data, including deprecated/experimental markers. All element functions return plain HTML strings — no virtual DOM, no runtime overhead.Packages
@fartlabs/ht— Plain TypeScriptType-safe, zero-runtime-dependency HTML string builder. Each HTML/SVG/MathML element is a TypeScript function that accepts typed props and optional string children and returns a
string.Install:
Quick start:
SVG example:
MathML example:
Full docs →
packages/ht/README.mdand https://jsr.io/@fartlabs/ht@fartlabs/htx— JSXWrite JSX that renders directly to HTML strings. Components are the UPPERCASE versions of HTML tag names (e.g.
DIV,H1,INPUT). Powered by@fartlabs/jsonx.Install:
Configure JSX in
deno.json:{ "compilerOptions": { "jsx": "react-jsx", "jsxImportSource": "@fartlabs/htx" } }Quick start (
main.tsx):Custom components:
Full docs →
packages/htx/README.mdand https://jsr.io/@fartlabs/htxRepository structure
Key differences between
@fartlabs/htand@fartlabs/htx@fartlabs/ht@fartlabs/htxdiv({class:"x"}, "child")<DIV class="x">child</DIV>a,div,h1)A,DIV,H1)...children: string[]childrenprop or rest parameters@fartlabs/jsonx@fartlabs/htCode generation
All files under
packages/*/src/elements/andpackages/*/src/global_attributes.tsare auto-generated. Do not edit them directly.To regenerate both packages from the latest MDN Browser Compatibility Data:
A weekly CI job (
.github/workflows/weekly.yaml) automatically updates the@mdn/browser-compat-datadependency, regenerates both packages, runs tests, and bumps the patch version of bothpackages/ht/deno.jsonandpackages/htx/deno.jsonwhen data changes.Contributing
If you change generation logic in
generate.ts, rundeno task generateand commit the resulting file changes.See individual package READMEs for package-specific notes:
packages/ht/README.mdpackages/htx/README.mdLicense
@fartlabs/ht— MIT License@fartlabs/htx— WTFPLDeveloped with ❤️ @FartLabs
Notes
The repository has no root
deno.jsonvisible in the file tree (onlydeno.lockandgenerate.tsat root), so the root README is purely documentation — it does not serve as a Deno workspace config. A rootdeno.jsonwould be the natural companion if workspace support were added.The
generate.tsfile is the single source of truth for both packages. Any changes to element generation must go through it.@fartlabs/htxdoes not have its own JSX runtime implementation — it delegates entirely to@fartlabs/jsonxvia re-export injsx-runtime.ts.The
@fartlabs/htxpackage has a separate README (packages/htx/README.md) that still references the old@fartlabs/htxJSR badge URL and GitHub Actions URL from the original standalone repo — these should be updated to point to the monorepo URLs once the root README exists.