@@ -206,7 +206,7 @@ export function ResolutionVisualizer({
showStateEditor = true,
showControls = true,
showFullValues = false,
-}: ResolutionVisualizerProps): JSX.Element {
+}: ResolutionVisualizerProps): React.JSX.Element {
const {
pointer,
stateSpec,
diff --git a/packages/programs-react/CHANGELOG.md b/packages/programs-react/CHANGELOG.md
index 428bb61ab8..2e762fc2fa 100644
--- a/packages/programs-react/CHANGELOG.md
+++ b/packages/programs-react/CHANGELOG.md
@@ -7,6 +7,15 @@ root [`CHANGELOG.md`](../../CHANGELOG.md).
## Unreleased
+### Changed
+
+- The `react` and `react-dom` peer ranges now include React 19
+ (`^18.0.0 || ^19.0.0`) ([#374]). The components' return types now
+ read `React.JSX.Element`, which both React 18 and 19 types define;
+ the global `JSX` they used before is gone in `@types/react` 19.
+- The `shiki`, `@shikijs/langs` and `@shikijs/themes` dependency ranges
+ now include version 3 (`^2.5.0 || ^3.0.0`) ([#374]).
+
## 0.1.0-preview.2 — 2026-10-07
### Changed
@@ -71,3 +80,4 @@ First publication.
[#323]: https://github.com/ethdebug/format/pull/323
[#342]: https://github.com/ethdebug/format/pull/342
[#349]: https://github.com/ethdebug/format/pull/349
+[#374]: https://github.com/ethdebug/format/pull/374
diff --git a/packages/programs-react/package.json b/packages/programs-react/package.json
index 36783d861b..61c0cfb630 100644
--- a/packages/programs-react/package.json
+++ b/packages/programs-react/package.json
@@ -52,9 +52,9 @@
"dependencies": {
"@ethdebug/format": "^0.1.0-draft.2",
"@ethdebug/pointers": "^0.1.0-preview.2",
- "@shikijs/langs": "^2.5.0",
- "@shikijs/themes": "^2.5.0",
- "shiki": "^2.5.0"
+ "@shikijs/langs": "^2.5.0 || ^3.0.0",
+ "@shikijs/themes": "^2.5.0 || ^3.0.0",
+ "shiki": "^2.5.0 || ^3.0.0"
},
"devDependencies": {
"@testing-library/dom": "^10.0.0",
@@ -70,8 +70,8 @@
"vitest": "^3.2.4"
},
"peerDependencies": {
- "react": "^18.0.0",
- "react-dom": "^18.0.0"
+ "react": "^18.0.0 || ^19.0.0",
+ "react-dom": "^18.0.0 || ^19.0.0"
},
"publishConfig": {
"access": "public"
diff --git a/packages/programs-react/src/components/CallInfoPanel.tsx b/packages/programs-react/src/components/CallInfoPanel.tsx
index e0e10ed2be..5ddb1cf3ad 100644
--- a/packages/programs-react/src/components/CallInfoPanel.tsx
+++ b/packages/programs-react/src/components/CallInfoPanel.tsx
@@ -74,7 +74,7 @@ function bannerClassName(info: ResolvedCallInfo): string {
export function CallInfoPanel({
showPointers = false,
className = "",
-}: CallInfoPanelProps): JSX.Element | null {
+}: CallInfoPanelProps): React.JSX.Element | null {
const { currentCallInfo } = useTraceContext();
if (!currentCallInfo) {
@@ -110,7 +110,7 @@ interface PointerRefItemProps {
function PointerRefItem({
ref_,
showPointer,
-}: PointerRefItemProps): JSX.Element {
+}: PointerRefItemProps): React.JSX.Element {
return (
{ref_.label}:
diff --git a/packages/programs-react/src/components/CallStackDisplay.tsx b/packages/programs-react/src/components/CallStackDisplay.tsx
index f8dfc4b052..95cfef65ca 100644
--- a/packages/programs-react/src/components/CallStackDisplay.tsx
+++ b/packages/programs-react/src/components/CallStackDisplay.tsx
@@ -60,7 +60,7 @@ function formatAsDecimal(hex: string): string {
export function CallStackDisplay({
className = "",
-}: CallStackDisplayProps): JSX.Element {
+}: CallStackDisplayProps): React.JSX.Element {
const { callStack, resolvedCallStack, jumpToStep } = useTraceContext();
if (callStack.length === 0) {
diff --git a/packages/programs-react/src/components/HighlightedInstruction.tsx b/packages/programs-react/src/components/HighlightedInstruction.tsx
index 86dddf447c..d64854e0a0 100644
--- a/packages/programs-react/src/components/HighlightedInstruction.tsx
+++ b/packages/programs-react/src/components/HighlightedInstruction.tsx
@@ -12,7 +12,7 @@ import { ShikiCodeBlock } from "#shiki/ShikiCodeBlock";
*
* @returns JSON representation of the highlighted instruction
*/
-export function HighlightedInstruction(): JSX.Element {
+export function HighlightedInstruction(): React.JSX.Element {
const { highlightedInstruction } = useProgramExampleContext();
return (
diff --git a/packages/programs-react/src/components/Opcodes.tsx b/packages/programs-react/src/components/Opcodes.tsx
index 3da00432d3..b42b48824c 100644
--- a/packages/programs-react/src/components/Opcodes.tsx
+++ b/packages/programs-react/src/components/Opcodes.tsx
@@ -15,7 +15,7 @@ import { Data, Program } from "@ethdebug/format";
*
* @returns Opcodes list element
*/
-export function Opcodes(): JSX.Element {
+export function Opcodes(): React.JSX.Element {
const {
instructions,
highlightedInstruction,
@@ -93,7 +93,7 @@ function Opcode(props: {
onClick: () => void;
onMouseEnter: () => void;
onMouseLeave: () => void;
-}): JSX.Element {
+}): React.JSX.Element {
const {
instruction,
active,
diff --git a/packages/programs-react/src/components/ProgramExampleContext.tsx b/packages/programs-react/src/components/ProgramExampleContext.tsx
index ff85ee0209..ab890d26c8 100644
--- a/packages/programs-react/src/components/ProgramExampleContext.tsx
+++ b/packages/programs-react/src/components/ProgramExampleContext.tsx
@@ -74,7 +74,7 @@ export function ProgramExampleContextProvider({
...props
}: ProgramExampleProps & {
children: React.ReactNode;
-}): JSX.Element {
+}): React.JSX.Element {
const { sources, instructions: dynamicInstructionsWithoutOffsets } = props;
const dynamicInstructions = computeOffsets(dynamicInstructionsWithoutOffsets);
diff --git a/packages/programs-react/src/components/SourceContents.tsx b/packages/programs-react/src/components/SourceContents.tsx
index 793e67e67d..819a4090a6 100644
--- a/packages/programs-react/src/components/SourceContents.tsx
+++ b/packages/programs-react/src/components/SourceContents.tsx
@@ -25,7 +25,7 @@ import { Materials, Program } from "@ethdebug/format";
*/
export function SourceContents(
props: Omit,
-): JSX.Element {
+): React.JSX.Element {
const { sources, highlightedInstruction, highlightMode } =
useProgramExampleContext();
diff --git a/packages/programs-react/src/components/TraceContext.tsx b/packages/programs-react/src/components/TraceContext.tsx
index 943a3eec44..0f9aad8731 100644
--- a/packages/programs-react/src/components/TraceContext.tsx
+++ b/packages/programs-react/src/components/TraceContext.tsx
@@ -268,7 +268,7 @@ export function TraceProvider({
templates = {},
resolveVariables: shouldResolve = true,
children,
-}: TraceProviderProps): JSX.Element {
+}: TraceProviderProps): React.JSX.Element {
const [currentStepIndex, setCurrentStepIndex] = useState(
Math.min(initialStepIndex, trace.length - 1),
);
diff --git a/packages/programs-react/src/components/TraceControls.tsx b/packages/programs-react/src/components/TraceControls.tsx
index dc3c8c4998..6ff5c6a93c 100644
--- a/packages/programs-react/src/components/TraceControls.tsx
+++ b/packages/programs-react/src/components/TraceControls.tsx
@@ -24,7 +24,7 @@ export function TraceControls({
showStepCount = true,
showOpcode = true,
className = "",
-}: TraceControlsProps): JSX.Element {
+}: TraceControlsProps): React.JSX.Element {
const {
currentStepIndex,
totalSteps,
@@ -124,7 +124,7 @@ export interface TraceProgressProps {
*/
export function TraceProgress({
className = "",
-}: TraceProgressProps): JSX.Element {
+}: TraceProgressProps): React.JSX.Element {
const { currentStepIndex, totalSteps, jumpToStep } = useTraceContext();
const progress = totalSteps > 1 ? currentStepIndex / (totalSteps - 1) : 0;
diff --git a/packages/programs-react/src/components/VariableInspector.tsx b/packages/programs-react/src/components/VariableInspector.tsx
index c538fc2c91..9eda380cc7 100644
--- a/packages/programs-react/src/components/VariableInspector.tsx
+++ b/packages/programs-react/src/components/VariableInspector.tsx
@@ -24,7 +24,7 @@ export function VariableInspector({
showTypes = false,
showPointers = false,
className = "",
-}: VariableInspectorProps): JSX.Element {
+}: VariableInspectorProps): React.JSX.Element {
const { currentVariables, currentInstruction } = useTraceContext();
if (!currentInstruction) {
@@ -77,7 +77,7 @@ function VariableItem({
variable,
showType,
showPointer,
-}: VariableItemProps): JSX.Element {
+}: VariableItemProps): React.JSX.Element {
const { identifier, type, pointer, value, error } = variable;
// Extract type name if available
@@ -136,7 +136,7 @@ export interface StackInspectorProps {
export function StackInspector({
maxEntries = 10,
className = "",
-}: StackInspectorProps): JSX.Element {
+}: StackInspectorProps): React.JSX.Element {
const { currentStep } = useTraceContext();
if (!currentStep || !currentStep.stack || currentStep.stack.length === 0) {
diff --git a/packages/programs-react/src/shiki/ShikiCodeBlock.tsx b/packages/programs-react/src/shiki/ShikiCodeBlock.tsx
index ebee076432..3bf44081d5 100644
--- a/packages/programs-react/src/shiki/ShikiCodeBlock.tsx
+++ b/packages/programs-react/src/shiki/ShikiCodeBlock.tsx
@@ -23,7 +23,7 @@ export function ShikiCodeBlock({
code,
className,
...highlightOptions
-}: ShikiCodeBlockProps): JSX.Element {
+}: ShikiCodeBlockProps): React.JSX.Element {
const highlighter = useHighlighter();
if (!highlighter) {
diff --git a/yarn.lock b/yarn.lock
index dd56e307cd..f28a56b09f 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -4830,6 +4830,16 @@
"@types/hast" "^3.0.4"
hast-util-to-html "^9.0.4"
+"@shikijs/core@3.23.0":
+ version "3.23.0"
+ resolved "https://registry.yarnpkg.com/@shikijs/core/-/core-3.23.0.tgz#79248ec4ad3de4fd5c12993f5c30cb071ec04812"
+ integrity sha512-NSWQz0riNb67xthdm5br6lAkvpDJRTgB36fxlo37ZzM2yq0PQFFzbd8psqC2XMPgCzo1fW6cVi18+ArJ44wqgA==
+ dependencies:
+ "@shikijs/types" "3.23.0"
+ "@shikijs/vscode-textmate" "^10.0.2"
+ "@types/hast" "^3.0.4"
+ hast-util-to-html "^9.0.5"
+
"@shikijs/engine-javascript@2.5.0":
version "2.5.0"
resolved "https://registry.yarnpkg.com/@shikijs/engine-javascript/-/engine-javascript-2.5.0.tgz#e045c6ecfbda6c99137547b0a482e0b87f1053fc"
@@ -4839,6 +4849,15 @@
"@shikijs/vscode-textmate" "^10.0.2"
oniguruma-to-es "^3.1.0"
+"@shikijs/engine-javascript@3.23.0":
+ version "3.23.0"
+ resolved "https://registry.yarnpkg.com/@shikijs/engine-javascript/-/engine-javascript-3.23.0.tgz#eae89a47913f486e5a05130d13b965c424c33b21"
+ integrity sha512-aHt9eiGFobmWR5uqJUViySI1bHMqrAgamWE1TYSUoftkAeCCAiGawPMwM+VCadylQtF4V3VNOZ5LmfItH5f3yA==
+ dependencies:
+ "@shikijs/types" "3.23.0"
+ "@shikijs/vscode-textmate" "^10.0.2"
+ oniguruma-to-es "^4.3.4"
+
"@shikijs/engine-oniguruma@2.5.0":
version "2.5.0"
resolved "https://registry.yarnpkg.com/@shikijs/engine-oniguruma/-/engine-oniguruma-2.5.0.tgz#230de5693cc1da6c9d59c7ad83593c2027274817"
@@ -4847,13 +4866,28 @@
"@shikijs/types" "2.5.0"
"@shikijs/vscode-textmate" "^10.0.2"
-"@shikijs/langs@2.5.0", "@shikijs/langs@^2.5.0":
+"@shikijs/engine-oniguruma@3.23.0":
+ version "3.23.0"
+ resolved "https://registry.yarnpkg.com/@shikijs/engine-oniguruma/-/engine-oniguruma-3.23.0.tgz#789421048d66ac1b33613169d6d18b9cc6e340ed"
+ integrity sha512-1nWINwKXxKKLqPibT5f4pAFLej9oZzQTsby8942OTlsJzOBZ0MWKiwzMsd+jhzu8YPCHAswGnnN1YtQfirL35g==
+ dependencies:
+ "@shikijs/types" "3.23.0"
+ "@shikijs/vscode-textmate" "^10.0.2"
+
+"@shikijs/langs@2.5.0":
version "2.5.0"
resolved "https://registry.yarnpkg.com/@shikijs/langs/-/langs-2.5.0.tgz#97ab50c495922cc1ca06e192985b28dc73de5d50"
integrity sha512-Qfrrt5OsNH5R+5tJ/3uYBBZv3SuGmnRPejV9IlIbFH3HTGLDlkqgHymAlzklVmKBjAaVmkPkyikAV/sQ1wSL+w==
dependencies:
"@shikijs/types" "2.5.0"
+"@shikijs/langs@3.23.0", "@shikijs/langs@^2.5.0 || ^3.0.0":
+ version "3.23.0"
+ resolved "https://registry.yarnpkg.com/@shikijs/langs/-/langs-3.23.0.tgz#00959d8b16c7f671221ae79b3ad8cde7e6a5c112"
+ integrity sha512-2Ep4W3Re5aB1/62RSYQInK9mM3HsLeB91cHqznAJMuylqjzNVAVCMnNWRHFtcNHXsoNRayP9z1qj4Sq3nMqYXg==
+ dependencies:
+ "@shikijs/types" "3.23.0"
+
"@shikijs/themes@2.5.0", "@shikijs/themes@^2.5.0":
version "2.5.0"
resolved "https://registry.yarnpkg.com/@shikijs/themes/-/themes-2.5.0.tgz#8c6aecf73f5455681c8bec15797cf678162896cb"
@@ -4861,6 +4895,13 @@
dependencies:
"@shikijs/types" "2.5.0"
+"@shikijs/themes@3.23.0", "@shikijs/themes@^2.5.0 || ^3.0.0":
+ version "3.23.0"
+ resolved "https://registry.yarnpkg.com/@shikijs/themes/-/themes-3.23.0.tgz#fd96ca5ad52639057995bc2093682884e1846f27"
+ integrity sha512-5qySYa1ZgAT18HR/ypENL9cUSGOeI2x+4IvYJu4JgVJdizn6kG4ia5Q1jDEOi7gTbN4RbuYtmHh0W3eccOrjMA==
+ dependencies:
+ "@shikijs/types" "3.23.0"
+
"@shikijs/types@2.5.0":
version "2.5.0"
resolved "https://registry.yarnpkg.com/@shikijs/types/-/types-2.5.0.tgz#e949c7384802703a48b9d6425dd41673c164df69"
@@ -4869,6 +4910,14 @@
"@shikijs/vscode-textmate" "^10.0.2"
"@types/hast" "^3.0.4"
+"@shikijs/types@3.23.0":
+ version "3.23.0"
+ resolved "https://registry.yarnpkg.com/@shikijs/types/-/types-3.23.0.tgz#d441571a058641926018ae3de99866f39e5bbdf2"
+ integrity sha512-3JZ5HXOZfYjsYSk0yPwBrkupyYSLpAE26Qc0HLghhZNGTZg/SKxXIIgoxOpmmeQP0RRSDJTk1/vPfw9tbw+jSQ==
+ dependencies:
+ "@shikijs/vscode-textmate" "^10.0.2"
+ "@types/hast" "^3.0.4"
+
"@shikijs/vscode-textmate@^10.0.2":
version "10.0.2"
resolved "https://registry.yarnpkg.com/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz#a90ab31d0cc1dfb54c66a69e515bf624fa7b2224"
@@ -10276,6 +10325,23 @@ hast-util-to-html@^9.0.4:
stringify-entities "^4.0.0"
zwitch "^2.0.4"
+hast-util-to-html@^9.0.5:
+ version "9.0.5"
+ resolved "https://registry.yarnpkg.com/hast-util-to-html/-/hast-util-to-html-9.0.5.tgz#ccc673a55bb8e85775b08ac28380f72d47167005"
+ integrity sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==
+ dependencies:
+ "@types/hast" "^3.0.0"
+ "@types/unist" "^3.0.0"
+ ccount "^2.0.0"
+ comma-separated-tokens "^2.0.0"
+ hast-util-whitespace "^3.0.0"
+ html-void-elements "^3.0.0"
+ mdast-util-to-hast "^13.0.0"
+ property-information "^7.0.0"
+ space-separated-tokens "^2.0.0"
+ stringify-entities "^4.0.0"
+ zwitch "^2.0.4"
+
hast-util-to-jsx-runtime@^2.0.0:
version "2.3.0"
resolved "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.0.tgz"
@@ -13436,6 +13502,11 @@ onetime@^7.0.0:
dependencies:
mimic-function "^5.0.0"
+oniguruma-parser@^0.12.2:
+ version "0.12.2"
+ resolved "https://registry.yarnpkg.com/oniguruma-parser/-/oniguruma-parser-0.12.2.tgz#e27ca446f7fcf0969662a3ab9b4f43176d62b139"
+ integrity sha512-6HVa5oIrgMC6aA6WF6XyyqbhRPJrKR02L20+2+zpDtO5QAzGHAUGw5TKQvwi5vctNnRHkJYmjAhRVQF2EKdTQw==
+
oniguruma-to-es@^3.1.0:
version "3.1.1"
resolved "https://registry.yarnpkg.com/oniguruma-to-es/-/oniguruma-to-es-3.1.1.tgz#480e4bac4d3bc9439ac0d2124f0725e7a0d76d17"
@@ -13445,6 +13516,15 @@ oniguruma-to-es@^3.1.0:
regex "^6.0.1"
regex-recursion "^6.0.2"
+oniguruma-to-es@^4.3.4:
+ version "4.3.6"
+ resolved "https://registry.yarnpkg.com/oniguruma-to-es/-/oniguruma-to-es-4.3.6.tgz#43e640280241b0d687a314e7a641d476407a1c4d"
+ integrity sha512-csuQ9x3Yr0cEIs/Zgx/OEt9iBw9vqIunAPQkx19R/fiMq2oGVTgcMqO/V3Ybqefr1TBvosI6jU539ksaBULJyA==
+ dependencies:
+ oniguruma-parser "^0.12.2"
+ regex "^6.1.0"
+ regex-recursion "^6.0.2"
+
open@^10.0.3:
version "10.2.0"
resolved "https://registry.yarnpkg.com/open/-/open-10.2.0.tgz#b9d855be007620e80b6fb05fac98141fe62db73c"
@@ -14728,6 +14808,11 @@ property-information@^6.0.0:
resolved "https://registry.npmjs.org/property-information/-/property-information-6.4.0.tgz"
integrity sha512-9t5qARVofg2xQqKtytzt+lZ4d1Qvj8t5B8fEwXK6qOfgRLgH/b13QlgEyDh033NOS31nXeFbYv7CLUDG1CeifQ==
+property-information@^7.0.0:
+ version "7.2.0"
+ resolved "https://registry.yarnpkg.com/property-information/-/property-information-7.2.0.tgz#0809b34264e995c0bfcd3227028a1e35210af80a"
+ integrity sha512-IAtzIB6sUiWaJYrX9smp3V46pBGbBeLFRGdh25kg1334VcBlD8HzhPeNIWQH9zhGmo2itIe25EHt9dQP7G5hmg==
+
proto-list@~1.2.1:
version "1.2.4"
resolved "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz"
@@ -15151,7 +15236,7 @@ regex-utilities@^2.3.0:
resolved "https://registry.yarnpkg.com/regex-utilities/-/regex-utilities-2.3.0.tgz#87163512a15dce2908cf079c8960d5158ff43280"
integrity sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==
-regex@^6.0.1:
+regex@^6.0.1, regex@^6.1.0:
version "6.1.0"
resolved "https://registry.yarnpkg.com/regex/-/regex-6.1.0.tgz#d7ce98f8ee32da7497c13f6601fca2bc4a6a7803"
integrity sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==
@@ -15805,6 +15890,20 @@ shiki@^2.5.0:
"@shikijs/vscode-textmate" "^10.0.2"
"@types/hast" "^3.0.4"
+"shiki@^2.5.0 || ^3.0.0":
+ version "3.23.0"
+ resolved "https://registry.yarnpkg.com/shiki/-/shiki-3.23.0.tgz#fca5332195e3afd6c94b384103ae9671a29c7fb9"
+ integrity sha512-55Dj73uq9ZXL5zyeRPzHQsK7Nbyt6Y10k5s7OjuFZGMhpp4r/rsLBH0o/0fstIzX1Lep9VxefWljK/SKCzygIA==
+ dependencies:
+ "@shikijs/core" "3.23.0"
+ "@shikijs/engine-javascript" "3.23.0"
+ "@shikijs/engine-oniguruma" "3.23.0"
+ "@shikijs/langs" "3.23.0"
+ "@shikijs/themes" "3.23.0"
+ "@shikijs/types" "3.23.0"
+ "@shikijs/vscode-textmate" "^10.0.2"
+ "@types/hast" "^3.0.4"
+
side-channel-list@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/side-channel-list/-/side-channel-list-1.0.0.tgz#10cb5984263115d3b7a0e336591e290a830af8ad"