---
title: Without JSX
description: Build views with h() when you cannot use JSX.
---

Prefer JSX. When a file cannot use the JSX runtime, call `h()`:

```ts twoslash
import { atom, h } from "ilha";

const Counter = () => {
  const count = atom(0);
  return h(
    "button",
    {
      type: "button",
      onclick: () => count.update((n: number) => n + 1),
    },
    "count: ",
    count,
  );
};
```

`h(type, props, ...children)` is the same factory JSX uses. There is no `html` tagged template in this API.

## Tagged templates

If you want markup that looks like the old html tagged-template helper, look at [@knighted/jsx](https://github.com/knightedcodemonkey/jsx). It is a tagged-template JSX runtime. It is **not** built into Ilha.

It is compatible with Ilha **only if** the tag emits `h()` vnodes (`$$ilha: 1`), not DOM nodes or `React.createElement`. The package defaults to React; override its `createElement` / `fragment` to `h` and `Fragment` from `ilha` if that option exists in the version you install.

Use lowercase event props (`onclick`, not `onClick`). Ilha only binds all-lowercase `on*` keys. `class` and `className` both work.

Prefer real JSX or `h()` for anything you ship. Treat `@knighted/jsx` as an optional authoring layer, not part of the Ilha contract.
