Rendering
A view returns one of two things: an Ignite JSX element (the default) or a lit-html template. Ignite renders each with the matching strategy, and it picks the strategy automatically from what the view returns — no ignite.config.ts, no plugin, and no renderer setting.
Two ways to author a view
Section titled “Two ways to author a view”Both styles use the same view/commands contract; they differ only in how you write the markup.
Ignite JSX (default)
Section titled “Ignite JSX (default)”JSX syntax, rendered by Ignite’s built-in diffing renderer. It ships with the package and registers itself:
const Counter = component('ignite-counter', ({ count }) => ( <output>Count: {count}</output>));JSX is compiled — <output> becomes a jsx(...) call at build time — so you must point the JSX transform at ignite-element/jsx (see Where jsxImportSource lives).
lit-html
Section titled “lit-html”A html tagged template, rendered by the lit strategy. Unlike JSX, a tagged template is plain runtime JavaScript — nothing to compile. Install lit-html and import the strategy once to register it:
import '@ignite-element/renderer/lit';import { html } from 'lit-html';
const Counter = component('ignite-counter', ({ count }) => html`<output>Count: ${count}</output>`);Where jsxImportSource lives
Section titled “Where jsxImportSource lives”Ignite JSX needs the compiler told to use its JSX runtime. That is the jsxImportSource setting, and it can live in any one of three places — pick whichever fits your project:
| Where | Use it when |
|---|---|
Global tsconfig.json — "jsxImportSource": "ignite-element/jsx" | Every JSX file is Ignite JSX. The common case; see Installation. |
Per-file pragma — /** @jsxImportSource ignite-element/jsx */ | You mix runtimes in one project (e.g. React app files alongside Ignite element files). |
Bundler config — esbuild/Vite jsxImportSource | You drive JSX through the bundler instead of tsconfig (e.g. a plain-JavaScript build). |
lit-html needs none of this — a html template is not compiled.
Renderer selection is automatic
Section titled “Renderer selection is automatic”On the config-free path, Ignite resolves the strategy from each view’s output:
- a lit-html
TemplateResult(with@ignite-element/renderer/litimported) → the lit strategy; - anything else → Ignite JSX.
A lit view rendered without importing the lit strategy falls back to Ignite JSX unchanged (no error) — importing the strategy is what upgrades it. To force one renderer project-wide regardless of output, set renderer in ignite.config.ts; that explicit override wins over auto-detection.
TypeScript is optional
Section titled “TypeScript is optional”Nothing here requires TypeScript — TS only adds type-checking on top. What a renderer needs depends on whether its markup is compiled:
| Authoring | No build step (raw .js in the browser) | With a bundler (.js/.jsx, no TS) |
|---|---|---|
lit-html (html template) | ✅ runtime tagged template | ✅ |
Ignite JSX (<div/> syntax) | ❌ JSX must be transformed | ✅ set jsxImportSource in the bundler |
Ignite JSX (jsx(...) calls) | ✅ plain function calls | ✅ |
<div/> is not valid JavaScript, so it cannot run untransformed. With no build step you can still use Ignite JSX by calling its runtime directly — jsx/jsxs/Fragment are exported from ignite-element/jsx/jsx-runtime, the same functions JSX compiles to:
import { jsx } from 'ignite-element/jsx/jsx-runtime';
const view = ({ count }) => jsx('output', { children: `Count: ${count}` });For a no-build setup, lit-html is usually the simpler choice: it needs only an import map for the bare ignite-element specifiers — the standard way to run ESM in the browser.
Related
Section titled “Related”- Installation — the
jsxImportSourcetsconfig setup. - Advanced config — the project-wide
rendereroverride, shared styles, and render-strategy primitives. - Styling — component CSS inside the shadow root.