The Deno CLI has a default configuration for JSX that is different than the
defaults for tsc
. Effectively Deno uses the following
options by default:
JSX import source
In React 17, the React team added what they called . This enhanced and modernized the API for JSX transforms as well as provided a mechanism to automatically import a JSX library into a module, instead of having to explicitly import it or make it part of the global scope. Generally this makes it easier to use JSX in your application.
As of Deno 1.16, initial support for these transforms was added. Deno supports both the JSX import source pragma as well as configuring a JSX import source in a configuration file.
JSX runtime
When using the automatic transforms, Deno will try to import a JSX runtime
module that is expected to conform to the new JSX API and is located at either
jsx-runtime
or jsx-dev-runtime
. For example if a JSX import source is
configured to react
, then the emitted code will add this to the emitted file:
import { jsx as jsx_ } from "react/jsx-runtime";
For example, if you wanted to use Preact from the
CDN, you would use https://esm.sh/preact
as the JSX
import source, and esm.sh will resolve https://esm.sh/preact/jsx-runtime
as a
module, including providing a header in the response that tells Deno where to
find the type definitions for Preact.
Using the JSX import source pragma
Whether you have a JSX import source configured for your project, or if you are
using the default “legacy” configuration, you can add the JSX import source
pragma to a .jsx
or module, and Deno will respect it.
The @jsxImportSource
pragma needs to be in the leading comments of the module.
For example to use Preact from esm.sh, you would do something like this:
Using JSX import source in a configuration file
If you want to configure a JSX import source for a whole project, so you don’t
need to insert the pragma on each module, you can use the "compilerOptions"
in
a configuration file to specify
this. For example if you were using Preact as your JSX library from esm.sh, you
would configure the following, in the configuration file:
{
"compilerOptions": {
"jsx": "react-jsx",
}
}
Using an import map
And then you could use the following pragma:
Or you could configure it in the compiler options:
You would then need to pass the --import-map
option on the command line (along
with the --config
option is using a config file) or set the deno.importMap
option (and deno.config
option) in your IDE.
Current limitations
There are two current limitations of the support of the JSX import source:
- A JSX module that does not have any imports or exports is not transpiled
properly when type checking (see:
).
Errors will be seen at runtime about
_jsx
not being defined. To work around the issue, addexport {}
to the file or use the--no-check
flag which will cause the module to be emitted properly. - Using
"jsx-reactdev"
compiler option is not supported with--no-emit
/bundling/compiling (see: swc-project/swc#2656). Various runtime errors will occur about not being able to loadjsx-runtime
modules. To work around the issue, use the compiler option instead, or don’t use--no-emit
, bundling or compiling.