Start here: If you're migrating an app, read the beta tester guide first: MIGRATION.md
Solid 2.0 moves JSX type ownership out of solid-js and into renderer packages. The core package owns renderer-neutral component and child types. @solidjs/web, @solidjs/h, and custom renderers own their JSX namespaces, intrinsic elements, and jsx-runtime / jsx-dev-runtime type entries.
For web apps, TypeScript should resolve JSX from @solidjs/web:
{
"compilerOptions": {
"jsx": "preserve",
"jsxImportSource": "@solidjs/web"
}
}solid-js is the renderer-neutral UI core, but its old TypeScript surface implicitly depended on DOM JSX types. That made non-web renderers and DOM-free TypeScript environments inherit web types even when they did not import @solidjs/web.
Renderer-owned JSX keeps the dependency direction aligned with runtime ownership:
solid-js // component model and renderer-neutral renderable values
@solidjs/web // DOM JSX namespace and DOM intrinsic elements
@solidjs/h // hyperscript JSX namespace
@solidjs/universal // custom renderer primitive, renderer supplies JSX types
Core component and child APIs use Element from solid-js. It represents values Solid can carry through component trees without naming DOM node types.
import type { Element, Component, ParentComponent } from "solid-js";
const App: Component = () => "hello";
const Layout: ParentComponent = props => props.children;Use this type for renderer-neutral component APIs. Do not import JSX from solid-js; it is no longer exported.
For DOM JSX, import renderer-specific helper types from @solidjs/web:
import type { ComponentProps, JSX } from "@solidjs/web";
type ButtonProps = ComponentProps<"button">;
type ClickHandler = JSX.EventHandler<HTMLButtonElement, MouseEvent>;@solidjs/web/jsx-runtime and @solidjs/web/jsx-dev-runtime provide the TypeScript JSX namespace for web projects. solid-js/jsx-runtime and solid-js/jsx-dev-runtime are removed.
Projects using the automatic JSX transform with hyperscript should point jsxImportSource at @solidjs/h:
{
"compilerOptions": {
"jsx": "react-jsx",
"jsxImportSource": "@solidjs/h"
}
}@solidjs/h keeps its distinct JSX element surface because hyperscript can represent function elements in ways DOM JSX should not.
Custom renderer packages should expose ./jsx-runtime and ./jsx-dev-runtime type entries and define their own JSX namespace. See @solidjs/universal for a minimal template.
Renderer packages that vendor dom-expressions JSX declarations can specialize JSX.Element at build time with dom-expressions-jsx-types.
| 1.x / old 2.0 beta | Replacement |
|---|---|
"jsxImportSource": "solid-js" |
"jsxImportSource": "@solidjs/web" for web JSX |
solid-js/jsx-runtime |
@solidjs/web/jsx-runtime |
solid-js/jsx-dev-runtime |
@solidjs/web/jsx-dev-runtime |
import type { JSX } from "solid-js" |
import type { JSX } from "@solidjs/web" |
ComponentProps<"button"> from solid-js |
ComponentProps<"button"> from @solidjs/web |
Renderer-neutral JSX.Element annotations |
Element from solid-js |
Removed from solid-js |
Replacement / notes |
|---|---|
JSX namespace export |
Import renderer JSX types from the renderer package |
JSXElement alias |
Use Element from solid-js for renderer-neutral values |
solid-js/jsx-runtime |
Use the renderer runtime, usually @solidjs/web/jsx-runtime |
solid-js/jsx-dev-runtime |
Use the renderer runtime, usually @solidjs/web/jsx-dev-runtime |
| DOM intrinsic element helper types | Import DOM helper types from @solidjs/web |
- Keeping a renderer-neutral
JSXnamespace insolid-jswas rejected because TypeScript's JSX namespace still becomes the source of renderer-specific intrinsic element and element-type behavior. - Keeping
solid-js/jsx-runtimeas a compatibility re-export was rejected because it would continue to makesolid-jslook like the JSX owner and hide incorrectjsxImportSourceconfiguration.