Tailwind classes in OCaml
OCaml 96.6%
Dune 0.4%
CSS 0.1%
Other 3.0%
12 1 0

Clone this repository

https://tangled.org/anil.recoil.org/ocaml-tailwind
git@git.recoil.org:anil.recoil.org/ocaml-tailwind

For self-hosted knots, clone URLs may differ based on your setup.

README.md

Tailwind OCaml#

An OCaml library for generating Tailwind CSS classes with compile-time validation and a companion HTML generation library using Htmlit.

This project provides two main libraries:

  • tailwind: Core library for type-safe Tailwind CSS class generation
  • tailwind-html: HTML component library built on top of Htmlit

Features#

  • Compile-time validation of Tailwind classes
  • Type-safe color variants and sizes
  • Exhaustive pattern matching for all utility classes

Comprehensive Coverage#

  • Typography: Font sizes, weights, line heights, text alignment, decorations
  • Layout: Display, position, flexbox, grid, spacing
  • Colors: Full color palette with variants
  • Effects: Shadows, borders, rounded corners, transitions
  • Responsive: Breakpoint-based responsive utilities
  • Variants: Hover, focus, and other state variants

Using Dune#

Add to your dune-project:

(package
 (name myproject)
 (depends
  ocaml
  dune
  tailwind
  tailwind-html
  htmlit))

Quick Start#

Basic Usage#

open Tailwind

(* Create a styled div *)
let styled_div = 
  let classes = tw [
    Display.flex;
    Flexbox.(to_class (justify `Center));
    Flexbox.(to_class (align_items `Center));
    Color.bg (Color.make `Gray ~variant:`V100 ());
    Spacing.(to_class (p (Size.rem 2.0)));
  ] in
  Printf.sprintf "<div class=\"%s\">Content</div>" (to_string classes)

With Htmlit Integration#

open Htmlit
open Tailwind

let classes_attr tailwind_classes = 
  At.class' (Tailwind.to_string tailwind_classes)

let create_card title content =
  El.div ~at:[classes_attr (tw [
    Patterns.card;
    Spacing.(to_class (p (Size.rem 1.5)));
    Effects.shadow_md;
  ])] [
    El.h2 ~at:[classes_attr (tw [
      Typography.(to_class (font_size `Xl));
      Typography.(to_class (font_weight `Bold));
      Spacing.(to_class (mb (Size.rem 1.0)));
    ])] [El.txt title];
    El.p [El.txt content];
  ]

Examples#

The examples/ directory contains several demonstration files:

Running Examples#

# Build all examples
dune build examples/

# Run comprehensive showcase (generates HTML + CSS)
dune exec examples/comprehensive_showcase.exe

# Run basic usage example
dune exec examples/basic_usage.exe

# Run HTML integration example  
dune exec examples/tailwind_html_example.exe

Comprehensive Showcase#

The comprehensive showcase demonstrates all library features and generates:

  • showcase.html - Complete HTML page with all Tailwind classes
  • input.css - Tailwind v4 CSS with custom theme extensions
dune exec examples/comprehensive_showcase.exe
# Then open showcase.html in your browser

Tailwind v4 Support#

This library supports Tailwind v4's CSS-first approach:

/* Generated input.css - no config file needed! */
@import "tailwindcss";

@theme {
  --font-sans: 'Inter', system-ui, sans-serif;
  --color-brand-600: #2563eb;
  /* Custom theme extensions */
}

To process the CSS:

npx tailwindcss@next -i input.css -o output.css

Module Documentation#

Core Modules#

Tailwind#

Main module that exports all utilities and provides the tw function for composing classes.

Color#

Type-safe color system with variants:

Color.bg (Color.make `Blue ~variant:`V600 ())
Color.text Color.white
Color.border (Color.make `Gray ~variant:`V200 ())

Typography#

Font utilities:

Typography.(to_class (font_size `Xl2))
Typography.(to_class (font_weight `Bold))
Typography.(to_class (line_height `Relaxed))

Spacing#

Margin and padding utilities:

Spacing.(to_class (p (Size.rem 1.0)))    (* padding *)
Spacing.(to_class (mx Size.auto))        (* margin-x auto *)
Spacing.(to_class (gap `All (Size.px 16.0))) (* gap *)

Layout#

Layout utilities:

Layout.(to_class (width (Size.percent 100.0)))
Layout.(to_class (height Size.screen))
Layout.(to_class (max_width (Size.rem 64.0)))

Flexbox#

Flexbox utilities:

Display.flex
Flexbox.(to_class (justify `Between))
Flexbox.(to_class (align_items `Center))
Flexbox.(to_class (direction `Col))

Grid#

CSS Grid utilities:

Display.grid
Grid.(to_class (template_cols (`Cols 3)))
Grid.(to_class (gap (Size.rem 1.0)))

Effects#

Visual effects:

Effects.shadow_lg
Effects.rounded_md
Effects.border
Effects.transition `All

Responsive#

Responsive utilities:

Responsive.(to_class (at_breakpoint `Md Display.flex))
Responsive.(to_class (at_breakpoint `Lg (Grid.(to_class (template_cols (`Cols 4))))))

Variants#

State variants:

Variants.hover (Color.bg (Color.make `Blue ~variant:`V700 ()))
Variants.focus Effects.ring

Patterns#

Common layout patterns:

Patterns.container ()
Patterns.card
Patterns.flex_center
Patterns.stack ~gap:(Size.rem 1.0) ()
Patterns.sticky_header

HTML Components (tailwind-html)#

Pre-built components using Htmlit:

open Tailwind_html

(* Button component *)
Button.primary ~text:"Click me" ~onclick:"handleClick()"

(* Card component *)
Card.simple ~title:"Card Title" ~content:"Card content here"

(* Layout components *)
Layout.container [
  Layout.row [
    Layout.col ~span:6 [content];
    Layout.col ~span:6 [content];
  ]
]

Testing#

Run the test suite:

dune test

Contributing#

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes with tests
  4. Submit a pull request

License#

MIT License - see LICENSE file for details

Acknowledgments#

Resources#