Askr
Fundamentals

Components and JSX

Use components and jsx with the current published Askr packages.

  • @askrjs/askr0.0.59

How to use components and jsx

Put reactive state inside the component that owns the interaction and derive display values from it during render.

  1. Import the published @askrjs/askr entrypoint.
  2. Keep components and jsx configuration next to the component, route, or server composition root that owns it.
  3. Handle pending, unavailable, cancellation, and failure states, then verify the production path.
import { derive, state } from '@askrjs/askr';

export function Quantity() {
  const count = state(1);
  const label = derive(() => 'Quantity: ' + count());

  return <button onClick={() => count.set(count() + 1)}>{label()}</button>;
}

Function components

A component is any function matching `(props: Props, context?: ComponentContext) => JSXElement | VNode` — it takes a props object and optionally a context carrying an `AbortSignal` and SSR details, and returns something renderable. There's no required base class or decorator; naming it with a capital letter is what tells JSX to treat it as a component instead of an intrinsic tag like `div`.

Props and children

Props arrive as a single object, typed loosely as `Props` — an index signature that accepts arbitrary attributes plus a `children` slot — so components can accept whatever shape makes sense for them. `children` isn't restricted to a single type: it can be a JSX element, a string, an array, or a function, and it's up to the component to decide what to do with it. Because props are just an object, spreading, defaulting, and destructuring work exactly the way they do anywhere else in TypeScript.

JSX runtime

Askr ships its own JSX transform, published from `@askrjs/askr/jsx-runtime` and `@askrjs/askr/jsx-dev-runtime`, along with a `Fragment` export for `<>...</>` grouping. Your build tooling needs `jsxImportSource` (or the equivalent tsconfig `jsx`/`jsxImportSource` fields) pointed at `@askrjs/askr` so JSX compiles to Askr's `jsx`/`jsxs` calls rather than React's. The intrinsic element types — `div`, `button`, `input`, and friends — are typed individually in the runtime's `KnownIntrinsicElementProps`, so props like `href` on `<a>` or `checked` on `<input>` are checked against the real HTML attribute, not a generic bag.

Composition

Because components are just functions returning JSX, composing them is normal function composition: nest a component inside another's JSX, pass callbacks and derived values as props, or wrap children with a boundary component like `ErrorBoundary`. There's no special API for higher-order components — wrapping one component to add behavior is a function that takes a component (or props) and returns JSX, the same pattern you'd use in any functional codebase.