#5480·hono

JSX type regression in 4.13.10: `IntrinsicElements` recursively references itself

Author: jeremybankaCreated Sep 29, 2026Updated Sep 29, 2026
Labelstriage

What version of Hono are you using?

4.13.10 (The reproduction passes with 4.13.9)

What runtime/platform is your app running on? (with version if possible)

Node.js 26.10.0, TypeScript 7.0.2

What steps can reproduce the bug?

Create these three files:

package.json

json
{
  "private": true,
  "type": "module",
  "devDependencies": {
    "hono": "4.13.10",
    "typescript": "7.0.2"
  }
}

tsconfig.json

json
{
  "compilerOptions": {
    "jsx": "react-jsx",
    "jsxImportSource": "hono/jsx",
    "lib": ["DOM", "ES2024"],
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "noEmit": true,
    "strict": true,
    "types": []
  },
  "include": ["index.tsx"]
}

index.tsx

typescript
export const valid = <button disabled={false}>Hello</button>

// @ts-expect-error disabled must be a boolean
export const invalid = <button disabled="yes">Hello</button>

Then, run

bash
npm install
npx tsc

The same failure can be seen using "jsxImportSource": "hono/jsx/dom".

What is the expected behavior?

Compilation should succeed. The valid element should pass the type-check; the invalid disabled attribute should produce an error covered by the @ts-expect-error.

What do you see instead?

node_modules/hono/dist/types/jsx/base.d.ts(20,13):
error TS2310: Type 'IntrinsicElements' recursively references itself as a base type.

index.tsx(3,1):
error TS2578: Unused '@ts-expect-error' directive.

The IntrinsicElements declaration is broken. As a result, features like standard attributes are no longer type-checked.

Additional information

Background

I caught this in CI for an automated hono upgrade today: https://github.com/jeremybanka/lasertag/pull/373

Diagnosis

The published 4.13.10 declaration in dist/types/jsx/base.d.ts imports IntrinsicElements without an alias, then uses the same name inside the JSX namespace:

bash
import { IntrinsicElements, JSX as JSX$1 } from "./intrinsic-elements.js";
      // ^ Not actually used! 
export declare namespace JSX {
  // ...
  interface IntrinsicElements extends IntrinsicElements {
    [tagName: string]: Props;
  }
}

In 4.13.9, the imported interface was aliased as IntrinsicElementsDefined, and the namespace interface extended that alias.

Restoring that alias resolves this reproduction for both JSX runtimes.