JSX automatic runtime with React configuration
To configure JSX with React using the automatic runtime in deno.json, set compilerOptions with jsx: "react-jsx" and jsxImportSource: "react". In the imports section, add react: "npm:react@^19" and @types/react: "npm:@types/react@^19". The @types/react package provides type checking and editor autocomplete for JSX. After editing imports, run deno install to download and cache packages.
JSX automatic runtime with Preact configuration
To configure JSX with Preact using the automatic runtime in deno.json, set compilerOptions with jsx: "react-jsx" and jsxImportSource: "preact". In the imports section, add preact: "npm:preact@^10". Preact ships its own types, so no separate @types package is needed.
JSX component as a function
In Deno with automatic JSX runtime configured, a component is simply a function that returns JSX. Example: export function Hello() { return <h1>Hello, world!</h1>; }
Classic React transform legacy behavior
Deno's built-in default predates the automatic runtime and uses the classic "react" transform, which compiles JSX to React.createElement calls and expects a React variable in scope. Code relying on the default throws ReferenceError: React is not defined at runtime unless you import React into every JSX file. The automatic runtime is preferred for new projects.
Preact for server-rendered HTML with precompile transform
Preact is a small, fast, React-compatible library that is a strong choice for server-rendered HTML. It works with the precompile transform for maximum speed. Fresh, Deno's web framework, uses Preact.
Hono JSX runtime for server-side rendering
Hono brings its own JSX runtime (hono/jsx) aimed at server-side rendering and edge deployments. It is the right choice when you are already building an API or site with Hono.
React ecosystem and server rendering considerations
React is the right choice when you need the React ecosystem, including React-only libraries, React Server Components, or an existing React codebase. React's server renderer is heavier than Preact's and does not support the precompile transform.
Switching JSX libraries
You can switch between React, Preact, and Hono libraries later by changing jsxImportSource in deno.json and the matching import. The JSX code you write stays the same.
Render Preact components to HTML on server
To render Preact components to HTML on the server, add preact-render-to-string to imports in deno.json, then import render from "preact-render-to-string" and use it to convert components to strings. Example: const html = `<!DOCTYPE html>${render(<App />)}`. Return the HTML in a Response with content-type: text/html; charset=utf-8 header.
Render React components to HTML on server
To render React components to HTML on the server, add react-dom to imports in deno.json, then import renderToString from "react-dom/server" and use it to convert components to strings. Example: const html = `<!DOCTYPE html>${renderToString(<App />)}`. Return the HTML in a Response with content-type: text/html; charset=utf-8 header.
React server renderer requires --allow-env permission
react-dom/server reads process.env.NODE_ENV, so a React server fails with NotCapable: Requires env access to "NODE_ENV" unless you grant environment access. Run it with -E or --allow-env flag alongside the network flag: deno run -N -E server.tsx. Preact's renderer does not read the environment and needs no extra permission.
Precompile transform for server-side rendering
Deno ships a precompile transform built for server-side rendering. It analyzes JSX at build time and turns static markup into prebuilt HTML strings, so the server skips most of the work of creating JSX objects on each request. Set jsx to "precompile" in compilerOptions in deno.json.
Precompile transform configuration with Preact
To use the precompile transform with Preact, set jsx: "precompile" and jsxImportSource: "preact" in compilerOptions in deno.json. Include preact and preact-render-to-string in imports.
Precompile transform library compatibility
The precompile transform works with Preact and Hono. It does not work with React: React's jsx-runtime does not export the jsxTemplate helper the transform relies on, so a React project configured this way fails with SyntaxError: ... does not provide an export named 'jsxTemplate'. Use the "react-jsx" runtime with React instead.
jsxPrecompileSkipElements option
If some elements must not be precompiled into static strings, list their tag names in jsxPrecompileSkipElements in compilerOptions in deno.json. Example: "jsxPrecompileSkipElements": ["a", "link"]
JSX pragma for per-file configuration
When most of your project uses one setup but a single file needs another, set the import source for that file with a pragma comment in the file's leading comments instead of changing deno.json. Example: /** @jsxImportSource npm:preact */
jsxImportSourceTypes pragma for separate types package
If the JSX library does not ship its own types, point Deno at a separate types package with @jsxImportSourceTypes pragma. Example: /** @jsxImportSource npm:react@^19 */ /** @jsxImportSourceTypes npm:@types/react@^19 */. This pragma is also available as a compiler option in deno.json.
jsx compiler option values and behavior
The jsx compiler option in compilerOptions in deno.json controls how Deno compiles JSX. Values and their behavior: "react-jsx" = automatic runtime, inserts imports from <jsxImportSource>/jsx-runtime (recommended); "react-jsxdev" = automatic runtime with debug info (file, line, column) added to each node (development only); "precompile" = optimized server-rendering transform for Preact and Hono (fastest for SSR); "react" = legacy classic transform, compiles to React.createElement, needs React in scope.
jsx compiler option related settings
Related to the jsx compiler option are: jsxImportSource (the module JSX imports come from: react, preact, hono/jsx; Deno appends /jsx-runtime automatically); jsxImportSourceTypes (a types package to use when the JSX library ships none); jsxPrecompileSkipElements (tag names to leave out of the precompile transform).
Deno JSX runs in .jsx and .tsx files with no build step
Deno runs JSX in .jsx and .tsx files with no build step. Configuration is done through deno.json to select which UI library to target, how to render JSX to HTML on the server, and the options that control the transform. If building an app with a framework, the framework usually sets this up automatically.