package html_of_jsx

  1. Overview
  2. Docs

Features

It's a very minimal library. It only provides 2 functions and a few helpers to make your life easier.

  • JSX.render to render an element to HTML
  • JSX.* to construct DOM Elements and DOM nodes (JSX.string, JSX.int, JSX.null, JSX.list, JSX.unsafe)

It's just HTML (no className, no htmlFor, etc.)

let element = <a href="https://x.com/davesnx">
  <span> {"Click me!"} </span>
</a>

> Note reserved keywords aren't possible as props. For example: class => class_ or type => type_.

Components are functions with labeled arguments

let component = (~name, ()) => {
  <div> <h1> {JSX.string("Hello, " ++ name ++ "!")} </h1> </div>;
};

JSX.render(<component name="lola" />);

> Note that the component function needs to have a last argument of type unit in order to work properly with labelled arguments. Explained on the OCaml manual: Functions with only labelled arguments, need a last non labelled argument to be able to be called as a non curried function.

Uppercase components default to make

module Button = {
  let make = () => {
    <button onclick="onClickHandler"> {JSX.string("Click me")} </button>;
  };
};

JSX.render(<Button />);
// is equivalent to
JSX.render(<Button.make />);

Brings the power of interleaving expressions within your JSX

let component = (~name, ~children, ()) => {
  <div>
    <h1> {("Hello, " ++ name ++ "!") |> JSX.string} </h1>
    <h2> children </h2>
  </div>;
};

JSX.render(
  <component name="World"> {JSX.string("This is a children!")} </component>,
);

List of childrens are available with JSX.list

JSX.render(
  <ul>
    {["This", "is", "an", "unordered", "list"]
     |> List.map(item => <li> {JSX.string(item)} </li>)
     |> JSX.list}
  </ul>,
);

Type-safe

HTML attributes are type-checked and only valid attributes are allowed, also ensures that the value is correct.

    <h1 noop=1> {JSX.string("Hello, world!")} </h1>
    ^^^
// Error: prop 'noop' is not valid on a 'h1' element.
    <h1 class_=1> {JSX.string("Hello, world!")} </h1>
               ^
// Error: This expression has type int but an expression was expected of type string

And also in case of a misspell, it recommends the closest attribute

          <div ?onClick />
          ^^^^
// Error: prop 'onClick' is not valid on a 'div' element.
//        Hint: Maybe you mean 'onclick'?

Minimalistic

Only 2 functions to learn, the rest are your own functions (aka components):

  • JSX.render to render your HTML
  • JSX.string to inline text

The rest are helpers on JSX.*, like (JSX.int). Check !JSX.

JSX.render(<h1>{JSX.string("Hello, world!")}</h1>);

children as a prop

This makes possible to compose any HTML and abstract those components away.

let component = (~name, ~children, ()) => {
  <div>
    <h1> {JSX.string("Hello, " ++ name ++ "!")} </h1>
    <h2> {children} </h2>
  </div>
};

JSX.render(<component> {"This is a children!"} </component>)

Supports list of elements as children

Construct many JSX.element without wrapping them in a HTML element.

let component: JSX.element =
  <>
    <div class_="md:w-1/3" />
    <div class_="md:w-2/3" />
  </>;

JSX.render(<component/>)

Works with Reason

let component = (~name, ()) => {
  <div>
    <h1> {JSX.string("Hello, " ++ name ++ "!")} </h1>
  </div>;
};

JSX.render(<component name="World" />);

Works with mlx

let component ~name () =
  <div>
    <h1> ("Hello, " ^ name ^ "!") </h1>
  </div>

JSX.render <component name="World" />
OCaml

Innovation. Community. Security.