diff --git a/CHANGELOG.md b/CHANGELOG.md
index 80d734f216..7d70ae26fe 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -40,6 +40,7 @@
- Prop punning when types don't match results in I/O error: _none_: No such file or directory. https://github.com/rescript-lang/rescript/pull/7533
- Pass location to children prop in jsx ppx. https://github.com/rescript-lang/rescript/pull/7540
- Fix crash when `bs-g` is used with untagged variants. https://github.com/rescript-lang/rescript/pull/7575
+- Fix issue with preserve mode where `jsx` is declared as an external without a `@module` attribute. https://github.com/rescript-lang/rescript/pull/7591
#### :nail_care: Polish
diff --git a/compiler/core/js_dump.ml b/compiler/core/js_dump.ml
index 99bfce9140..1684aa056c 100644
--- a/compiler/core/js_dump.ml
+++ b/compiler/core/js_dump.ml
@@ -533,12 +533,13 @@ and expression_desc cxt ~(level : int) f x : cxt =
( ({
expression_desc =
J.Var
- (J.Qualified
- ( _,
- Some fnName
- (* We care about the function name when it is jsxs,
+ ( Id {name = fnName}
+ | J.Qualified
+ ( _,
+ Some fnName
+ (* We care about the function name when it is jsxs,
If this is the case, we need to unpack an array later on *)
- ));
+ ) );
} as e),
el,
{call_transformed_jsx = true} )
diff --git a/tests/tests/src/jsx_preserve_test.mjs b/tests/tests/src/jsx_preserve_test.mjs
index 3c71b71dc7..9cf576055e 100644
--- a/tests/tests/src/jsx_preserve_test.mjs
+++ b/tests/tests/src/jsx_preserve_test.mjs
@@ -208,6 +208,12 @@ let _props_with_hyphen = ;
+let React = {};
+
+let _fragment =
+ {"Hello, world!"}
+;
+
export {
Icon,
_single_element_child,
@@ -234,5 +240,7 @@ export {
ComponentWithOptionalProps,
_optional_props,
_props_with_hyphen,
+ React,
+ _fragment,
}
/* _single_element_child Not a pure module */
diff --git a/tests/tests/src/jsx_preserve_test.res b/tests/tests/src/jsx_preserve_test.res
index 1c83f06f26..f9e0cf1661 100644
--- a/tests/tests/src/jsx_preserve_test.res
+++ b/tests/tests/src/jsx_preserve_test.res
@@ -128,3 +128,16 @@ module ComponentWithOptionalProps = {
let _optional_props = } />
let _props_with_hyphen =
+
+module React = {
+ type component<'props> = Jsx.component<'props>
+ type element = Jsx.element
+
+ external jsx: (component<'props>, 'props) => element = "jsx"
+
+ type fragmentProps = {children?: element}
+
+ external jsxFragment: component = "Fragment"
+}
+
+let _fragment = <> {Jsx.string("Hello, world!")} >