fluent-html
Zero-dependency, type-safe HTML builder for TypeScript with compile-time Tailwind CSS and HTMX safety
Overview
fluent-html is a zero-dependency, type-safe HTML builder library for TypeScript (7,531 lines of source, 6,733 lines of tests, ~247 commits over 2 years). It provides full compile-time safety for Tailwind CSS classes, HTMX attributes, route endpoints, element IDs, and form fields -- eliminating entire categories of runtime bugs while providing IDE autocomplete that makes documentation unnecessary. The library powers JT Digital's fullstack output with Fastify v5 + HTMX + Tailwind.
Architecture
The codebase is split into 6 sub-packages with separate entry points enabling tree-shaking: core (Tag class, types, guards, mixins), elements (55+ HTML factories), control (IfThen, Match, ForEach, context), render (sync + stream), fold (recursion schemes), and routes/ids/htmx. Tag's functionality is distributed via TypeScript declaration merging + prototype assignment -- a mixin architecture that keeps the class extensible without monolithic inheritance.
Key Concepts
Variant Prefix State Machine
The .on() and .at() methods implement a stack-based variant prefix system. Each call saves the current prefix, sets a new compound prefix, calls the callback, then restores. Nested variants compose correctly: .on('hover', t => t.on('focus', t => t.ring('2'))) produces hover:focus:ring-2.
Type-Level Route Parameter Extraction
defineRoutes performs compile-time extraction of :param segments from path strings using recursive template literal types. Combined with HasParams and ResolveParamTypes, routes without params get a simple signature while routes with params require a typed params object -- all enforced at the type level with zero runtime cost.
Code Highlights
export type Thunk<T> = () => T;
export type View = Tag | string | RawString | View[];export function hyloView<S, A>(
coalg: ViewCoalgebra<S>, alg: ViewAlgebra<A>, seed: S
): A {
const layer = coalg(seed);
switch (layer.type) {
case "text":
return alg.text(layer.value);
case "raw":
return alg.raw(layer.html);
case "tag": {
const children = alg.list(
layer.children.map(s => hyloView(coalg, alg, s))
);
return alg.tag(layer.element, layer.attrs, children);
}
case "list":
return alg.list(layer.items.map(s => hyloView(coalg, alg, s)));
}
}type ExtractParams<Path extends string> =
Path extends `${string}:${infer Param}/${infer Rest}`
? Param | ExtractParams<`/${Rest}`>
: Path extends `${string}:${infer Param}`
? Param
: never;
type ResolveParamTypes<
Path extends string,
Params extends Readonly<Record<string, ParamTypeName>> | undefined,
> = {
[K in ExtractParams<Path>]: Params extends Record<string, ParamTypeName>
? K extends keyof Params
? ParamTypeMap[Params[K]] : string
: string;
};Highlights
- Designed a mixin architecture using TypeScript declaration merging + prototype assignment that splits a 1,100-line Tag class into focused modules with zero API changes
- Implemented four recursion schemes (catamorphism, paramorphism, anamorphism, hylomorphism) on HTML trees with fusion law tests
- Built a compile-time route safety system using recursive template literal types that extracts :param segments and resolves TypeScript types with zero runtime overhead
- Engineered a multi-layer XSS protection system backed by property-based fuzz testing (1,000 random inputs per property)
- Created a complete developer toolchain: 19-rule ESLint plugin, Tailwind CSS content extractor, and benchmark suite
Related Projects
PromiseKit
Production Promise library built from algebraic first principles, shipped to ~50K DAU across multiple iOS apps
Designed and built a production Promise library from algebraic first principles -- map derives from flatMap, reduce from fold, operators match Haskell's typeclass precedence hierarchy
Redis Server (Zig)
From-scratch Redis-compatible server in Zig with RESP parsing, RDB persistence, and master-replica replication
Implemented a complete Redis-compatible server from scratch in 915 lines of zero-dependency Zig with RESP protocol parser, key-value store with TTL, and RDB binary format codec
Algorithm Competitions
Two 1st places and one 2nd/3rd place across three timed MSc algorithm competitions
1st place — Progressive Chess: A* converted to greedy best-first (g=0), Zobrist hashing with incremental XOR, composable per-piece heuristic dispatch, pawn promotion pruning