diff --git a/crates/oxc_linter/src/rules/eslint/no_unused_vars/tests/mod.rs b/crates/oxc_linter/src/rules/eslint/no_unused_vars/tests/mod.rs
index 56e51fd9da359..ff47bc2485d96 100644
--- a/crates/oxc_linter/src/rules/eslint/no_unused_vars/tests/mod.rs
+++ b/crates/oxc_linter/src/rules/eslint/no_unused_vars/tests/mod.rs
@@ -1,5 +1,6 @@
mod eslint;
mod oxc;
+mod react;
mod typescript_eslint;
use super::NoUnusedVars;
diff --git a/crates/oxc_linter/src/rules/eslint/no_unused_vars/tests/react.rs b/crates/oxc_linter/src/rules/eslint/no_unused_vars/tests/react.rs
new file mode 100644
index 0000000000000..65e6cb9b4f216
--- /dev/null
+++ b/crates/oxc_linter/src/rules/eslint/no_unused_vars/tests/react.rs
@@ -0,0 +1,133 @@
+//! Test cases from eslint-plugin-react (jsx/no-uses-vars)
+
+use super::NoUnusedVars;
+use crate::{tester::Tester, RuleMeta as _};
+
+/// !!!! STOP !!!!
+/// Are you fixing a bug in this rule and want to add a test case? Please put
+/// it in `oxc.rs`. These are _only_ the test cases ported from the original
+/// React rule.
+#[test]
+fn test() {
+ let pass = vec![
+ "
+ var App;
+ React.render();
+ ",
+ "
+ function foo() {
+ var App;
+ var bar = React.render();
+ return bar;
+ };
+ foo()
+ ",
+ "
+ var a = 1;
+ React.render();
+ ",
+ "
+ var App;
+ function f() {
+ return ;
+ }
+ f();
+ ",
+ "
+ var App;
+
+ ",
+ "
+ class HelloMessage {};
+
+ ",
+ "
+ class HelloMessage {
+ render() {
+ var HelloMessage =
Hello
;
+ return HelloMessage;
+ }
+ };
+
+ ",
+ "
+ function foo() {
+ var App = { Foo: { Bar: {} } };
+ var bar = React.render();
+ return bar;
+ };
+ foo()
+ ",
+ "
+ function foo() {
+ var App = { Foo: { Bar: { Baz: {} } } };
+ var bar = React.render();
+ return bar;
+ };
+ foo()
+ ",
+ "
+ var object;
+ React.render();
+ ",
+ "
+ var object;
+ React.render();
+ ",
+ ];
+
+ let fail = vec![
+ "
+ var App;
+ ",
+ r#"
+ var App;
+ var unused;
+ React.render();
+ "#,
+ "
+ var App;
+ var Hello;
+ React.render();
+ ",
+ r#"
+ var Button;
+ var Input;
+ React.render();
+ "#,
+ "
+ class unused {}
+ ",
+ "
+ class HelloMessage {
+ render() {
+ var HelloMessage = Hello
;
+ return HelloMessage;
+ }
+ }
+ ",
+ "
+ import {Hello} from 'Hello';
+ function Greetings() {
+ const Hello = require('Hello').default;
+ return ;
+ }
+ Greetings();
+ ",
+ "
+ var lowercase;
+ React.render();
+ ",
+ "
+ function Greetings(div) {
+ return ;
+ }
+ Greetings();
+ ",
+ ];
+
+ Tester::new(NoUnusedVars::NAME, NoUnusedVars::CATEGORY, pass, fail)
+ .intentionally_allow_no_fix_tests()
+ .with_snapshot_suffix("eslint-plugin-react")
+ .test_and_snapshot();
+}
diff --git a/crates/oxc_linter/src/snapshots/eslint_no_unused_vars@eslint-plugin-react.snap b/crates/oxc_linter/src/snapshots/eslint_no_unused_vars@eslint-plugin-react.snap
new file mode 100644
index 0000000000000..41c6521bbb6cd
--- /dev/null
+++ b/crates/oxc_linter/src/snapshots/eslint_no_unused_vars@eslint-plugin-react.snap
@@ -0,0 +1,103 @@
+---
+source: crates/oxc_linter/src/tester.rs
+snapshot_kind: text
+---
+ ⚠ eslint(no-unused-vars): Variable 'App' is declared but never used. Unused variables should start with a '_'.
+ ╭─[no_unused_vars.tsx:2:8]
+ 1 │
+ 2 │ var App;
+ · ─┬─
+ · ╰── 'App' is declared here
+ 3 │
+ ╰────
+ help: Consider removing this declaration.
+
+ ⚠ eslint(no-unused-vars): Variable 'unused' is declared but never used. Unused variables should start with a '_'.
+ ╭─[no_unused_vars.tsx:3:16]
+ 2 │ var App;
+ 3 │ var unused;
+ · ───┬──
+ · ╰── 'unused' is declared here
+ 4 │ React.render();
+ ╰────
+ help: Consider removing this declaration.
+
+ ⚠ eslint(no-unused-vars): Variable 'App' is declared but never used. Unused variables should start with a '_'.
+ ╭─[no_unused_vars.tsx:2:8]
+ 1 │
+ 2 │ var App;
+ · ─┬─
+ · ╰── 'App' is declared here
+ 3 │ var Hello;
+ ╰────
+ help: Consider removing this declaration.
+
+ ⚠ eslint(no-unused-vars): Variable 'Hello' is declared but never used. Unused variables should start with a '_'.
+ ╭─[no_unused_vars.tsx:3:16]
+ 2 │ var App;
+ 3 │ var Hello;
+ · ──┬──
+ · ╰── 'Hello' is declared here
+ 4 │ React.render();
+ ╰────
+ help: Consider removing this declaration.
+
+ ⚠ eslint(no-unused-vars): Variable 'Input' is declared but never used. Unused variables should start with a '_'.
+ ╭─[no_unused_vars.tsx:3:8]
+ 2 │ var Button;
+ 3 │ var Input;
+ · ──┬──
+ · ╰── 'Input' is declared here
+ 4 │ React.render();
+ ╰────
+ help: Consider removing this declaration.
+
+ ⚠ eslint(no-unused-vars): Class 'unused' is declared but never used.
+ ╭─[no_unused_vars.tsx:2:10]
+ 1 │
+ 2 │ class unused {}
+ · ───┬──
+ · ╰── 'unused' is declared here
+ 3 │
+ ╰────
+ help: Consider removing this declaration.
+
+ ⚠ eslint(no-unused-vars): Class 'HelloMessage' is declared but never used.
+ ╭─[no_unused_vars.tsx:2:10]
+ 1 │
+ 2 │ class HelloMessage {
+ · ──────┬─────
+ · ╰── 'HelloMessage' is declared here
+ 3 │ render() {
+ ╰────
+ help: Consider removing this declaration.
+
+ ⚠ eslint(no-unused-vars): Identifier 'Hello' is imported but never used.
+ ╭─[no_unused_vars.tsx:2:12]
+ 1 │
+ 2 │ import {Hello} from 'Hello';
+ · ──┬──
+ · ╰── 'Hello' is imported here
+ 3 │ function Greetings() {
+ ╰────
+ help: Consider removing this import.
+
+ ⚠ eslint(no-unused-vars): Variable 'lowercase' is declared but never used. Unused variables should start with a '_'.
+ ╭─[no_unused_vars.tsx:2:8]
+ 1 │
+ 2 │ var lowercase;
+ · ────┬────
+ · ╰── 'lowercase' is declared here
+ 3 │ React.render();
+ ╰────
+ help: Consider removing this declaration.
+
+ ⚠ eslint(no-unused-vars): Parameter 'div' is declared but never used. Unused parameters should start with a '_'.
+ ╭─[no_unused_vars.tsx:2:23]
+ 1 │
+ 2 │ function Greetings(div) {
+ · ─┬─
+ · ╰── 'div' is declared here
+ 3 │ return ;
+ ╰────
+ help: Consider removing this parameter.