Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/andresilva-cc/grafex/llms.txt

Use this file to discover all available pages before exploring further.

Grafex compositions are written in TSX but do not use React. Understanding why — and what the correct TypeScript configuration looks like — saves you from confusing type errors and misplaced imports before you write a single component.
Grafex ships its own JSX runtime (h and Fragment exported from the grafex package). It is not React, does not depend on React, and does not produce React elements. The h function serialises JSX directly to HTML strings, which are then passed to a headless WebKit browser for screenshotting.

Why a custom JSX runtime?

When TypeScript or esbuild sees a JSX expression like <div style={{ color: 'red' }}>Hello</div>, it rewrites it to a function call. The jsxFactory compiler option tells it which function to call — by default this is React.createElement, but Grafex replaces that with its own h function. The h function in Grafex’s runtime serialises element trees directly to HTML strings without any virtual DOM or reconciliation. This means:
  • Compositions have no runtime dependency — no import React from 'react' needed.
  • The output is a plain HTML string that can be injected into a browser page without a hydration step.
  • h and Fragment are injected by esbuild at transpile time — you never import them manually in a composition file.

Required compiler options

Three tsconfig.json compiler options are mandatory for Grafex to work correctly:
OptionValuePurpose
jsx"react"Tells TypeScript to rewrite JSX to function calls (not preserve it or use the automatic runtime).
jsxFactory"h"Names h as the function that each JSX element compiles down to.
jsxFragmentFactory"Fragment"Names Fragment as the function used for <>...</> shorthand syntax.
Do not set jsx to "react-jsx" or "react-jsxdev". Those modes use the automatic JSX transform which imports from react/jsx-runtime at compile time — a package that is not installed and is not needed. Only the classic "react" mode works with Grafex.

Automatic setup with grafex init

The fastest way to get the right configuration is to run:
npx grafex init
This creates a tsconfig.json with exactly the options Grafex needs, and a starter composition.tsx. If a tsconfig.json already exists in the current directory it is skipped without overwriting — so it is safe to run in an existing project.

Manual setup

If you did not use grafex init, or if you need to merge these settings into an existing tsconfig.json, add the three compiler options yourself:
{
  "compilerOptions": {
    "jsx": "react",
    "jsxFactory": "h",
    "jsxFragmentFactory": "Fragment"
  }
}
You can combine these with any other compiler options your project uses — strict, target, moduleResolution, path aliases, and so on. Only these three options are specific to Grafex.

JSX type definitions

Grafex ships its own JSX type definitions that cover JSX.Element, JSX.IntrinsicElements, inline style prop types (via csstype), and all standard HTML attributes. The declaration file is referenced automatically from dist/index.d.ts via a /// <reference path="./jsx.d.ts" /> directive, so they are picked up as soon as the package is installed — no extra imports or /// <reference> directives needed in your composition files. This means TypeScript will correctly type-check your JSX markup, autocomplete HTML attribute names, and catch style property typos, all without any extra setup.

Writing a composition

Once the tsconfig is in place, every .tsx file follows the same two-export structure:
import type { CompositionConfig } from 'grafex';

export const config: CompositionConfig = {
  width: 1200,
  height: 630,
};

export default function Card() {
  return (
    <div
      style={{
        width: '100%',
        height: '100%',
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center',
        fontFamily: 'system-ui, sans-serif',
        fontSize: '48px',
      }}
    >
      Ready to render
    </div>
  );
}
Notice there is no import { h, Fragment } from 'grafex' at the top. Those are injected by esbuild when Grafex transpiles the file — adding the import yourself would cause a double-declaration error.
The only import you typically need in a composition file is import type { CompositionConfig } from 'grafex' for the config type. Type-only imports are erased at compile time and never affect the runtime bundle.

Build docs developers (and LLMs) love