jsconfig.json option

jsx

  • Default not set
  • Tested with TypeScript 5.9

JSX is not JavaScript, so the checker reads it only when jsx is set; until then every element is TS17004. In a checked JavaScript project, the value mostly says who compiles the JSX: "preserve" leaves it to your bundler or framework, "react-jsx" describes React's automatic runtime (and other libraries through jsxImportSource).

Once it is set, JSX in .jsx files is checked like everything else: expressions inside braces, component props from JSDoc, element names against the JSX namespace your framework's types provide.

At a glance

Write "preserve" when a bundler or framework compiles your JSX; "react-jsx" (with jsxImportSource for other libraries) to match a React-style runtime
On the command line --jsx
Type string
Default in TypeScript 5.9 not set
TypeScript's description Specify what JSX code is generated.

The description is quoted from TypeScript's own option list (Apache-2.0); see the notices.

Examples

Greeting.jsx Error confirmed 5.9.3 TypeScript 5.9.3, run 21 October 2026: Greeting.jsx(4,10): error TS17004: Cannot use JSX unless the '--jsx' flag is provided. 6.0.3 TypeScript 6.0.3, run 21 October 2026: the same as 5.9.3. Greeting.jsx(4,10): error TS17004: Cannot use JSX unless the '--jsx' flag is provided. 7.0.2 TypeScript 7.0.2, run 21 October 2026: the same as 5.9.3. Greeting.jsx(4,10): error TS17004: Cannot use JSX unless the '--jsx' flag is provided. checked 21 October 2026
/** @param {{ name: string }} props */
export function Greeting({ name }) {
  return <p className="greeting">Hello, {name}</p>;error TS17004: Cannot use JSX unless the '--jsx' flag is provided.
}
A .jsx file without the jsx option.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": []
  },
  "include": [
    "*.jsx",
    "*.d.ts"
  ]
}
Greeting.jsx Error confirmed 5.9.3 TypeScript 5.9.3, run 21 October 2026: Greeting.jsx(4,42): error TS2304: Cannot find name 'nmae'. 6.0.3 TypeScript 6.0.3, run 21 October 2026: the same as 5.9.3. Greeting.jsx(4,42): error TS2304: Cannot find name 'nmae'. 7.0.2 TypeScript 7.0.2, run 21 October 2026: the same as 5.9.3. Greeting.jsx(4,42): error TS2304: Cannot find name 'nmae'. checked 21 October 2026
/** @param {{ name: string }} props */
export function Greeting({ name }) {
  return <p className="greeting">Hello, {nmae}</p>;error TS2304: Cannot find name 'nmae'.
}
jsx "preserve": the JSX is checked, typo included.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": [],
    "jsx": "preserve"
  },
  "include": [
    "*.jsx",
    "*.d.ts"
  ]
}

Including .jsx files

An include pattern that names *.js does not match .jsx. Write "src/**/*.jsx" too, or a folder name such as "src", which picks up both. The examples include their .jsx file by pattern and declare a tiny JSX namespace in a .d.ts; a real project gets that namespace from its framework's types package.

Gotchas

  • tsc --init in TypeScript 5.9 writes "jsx": "react-jsx". In a project without JSX it does nothing; in a project whose JSX is not React, change it.

Sources

Last reviewed 20 October 2026.