diff --git a/README.md b/README.md
index 3a06ef705d..0f2d5265e8 100644
--- a/README.md
+++ b/README.md
@@ -175,6 +175,7 @@ Enable the rules that you would like to use.
* [react/jsx-no-comment-textnodes](docs/rules/jsx-no-comment-textnodes.md): Comments inside children section of tag should be placed inside braces
* [react/jsx-no-duplicate-props](docs/rules/jsx-no-duplicate-props.md): Enforce no duplicate props
* [react/jsx-no-literals](docs/rules/jsx-no-literals.md): Prevent using string literals in React component definition
+* [react/jsx-no-namespace](docs/rules/jsx-no-namespace.md): Enforce that namespaces are not used in JSX
* [react/jsx-no-script-url](docs/rules/jsx-no-script-url.md): Forbid `javascript:` URLs
* [react/jsx-no-target-blank](docs/rules/jsx-no-target-blank.md): Forbid `target="_blank"` attribute without `rel="noreferrer"`
* [react/jsx-no-undef](docs/rules/jsx-no-undef.md): Disallow undeclared variables in JSX
diff --git a/docs/rules/jsx-no-namespace.md b/docs/rules/jsx-no-namespace.md
new file mode 100644
index 0000000000..8646d89164
--- /dev/null
+++ b/docs/rules/jsx-no-namespace.md
@@ -0,0 +1,29 @@
+# Enforce that namespaces are not used in JSX (react/jsx-no-namespace)
+
+Enforces the absence of a namespace in JSX components, such as with `svg:circle`, as they are not supported in React.
+
+## Rule Details
+
+The following patterns are considered warnings:
+
+```jsx
+
+```
+
+```jsx
+
+```
+
+The following patterns are **not** considered warnings:
+
+```jsx
+
+```
+
+```jsx
+
+```
+
+## When not to use
+
+If you are not using JSX.
diff --git a/index.js b/index.js
index 53b50230f4..9fb60a49b4 100644
--- a/index.js
+++ b/index.js
@@ -35,6 +35,7 @@ const allRules = {
'jsx-no-comment-textnodes': require('./lib/rules/jsx-no-comment-textnodes'),
'jsx-no-duplicate-props': require('./lib/rules/jsx-no-duplicate-props'),
'jsx-no-literals': require('./lib/rules/jsx-no-literals'),
+ 'jsx-no-namespace': require('./lib/rules/jsx-no-namespace'),
'jsx-no-script-url': require('./lib/rules/jsx-no-script-url'),
'jsx-no-target-blank': require('./lib/rules/jsx-no-target-blank'),
'jsx-no-useless-fragment': require('./lib/rules/jsx-no-useless-fragment'),
@@ -126,6 +127,7 @@ module.exports = {
'react/jsx-key': 2,
'react/jsx-no-comment-textnodes': 2,
'react/jsx-no-duplicate-props': 2,
+ 'react/jsx-no-namespace': 2,
'react/jsx-no-target-blank': 2,
'react/jsx-no-undef': 2,
'react/jsx-uses-react': 2,
diff --git a/lib/rules/jsx-no-namespace.js b/lib/rules/jsx-no-namespace.js
new file mode 100644
index 0000000000..ecb3173180
--- /dev/null
+++ b/lib/rules/jsx-no-namespace.js
@@ -0,0 +1,40 @@
+/**
+ * @fileoverview Enforce that namespaces are not used in JSX
+ * @author Yacine Hmito
+ */
+
+'use strict';
+
+const elementType = require('jsx-ast-utils/elementType');
+const docsUrl = require('../util/docsUrl');
+
+// ------------------------------------------------------------------------------
+// Rule Definition
+// ------------------------------------------------------------------------------
+
+module.exports = {
+ meta: {
+ docs: {
+ description: 'Enforce that namespaces are not used in JSX',
+ category: 'Possible Errors',
+ recommended: true,
+ url: docsUrl('jsx-no-namespace')
+ },
+
+ schema: [{
+ type: 'object',
+ additionalProperties: false
+ }]
+ },
+
+ create(context) {
+ return {
+ JSXOpeningElement(node) {
+ const name = elementType(node);
+ if (name.indexOf(':') === -1) return undefined;
+ const message = `JSX component ${name} must not be in a namespace as React does not support them`;
+ context.report({node, message});
+ }
+ };
+ }
+};
diff --git a/tests/lib/rules/jsx-no-namespace.js b/tests/lib/rules/jsx-no-namespace.js
new file mode 100644
index 0000000000..0ef901d6c1
--- /dev/null
+++ b/tests/lib/rules/jsx-no-namespace.js
@@ -0,0 +1,80 @@
+/**
+ * @fileoverview Tests for jsx-no-namespace
+ * @author Yacine Hmito
+ */
+
+'use strict';
+
+// ------------------------------------------------------------------------------
+// Requirements
+// ------------------------------------------------------------------------------
+
+const RuleTester = require('eslint').RuleTester;
+const rule = require('../../../lib/rules/jsx-no-namespace');
+
+const parserOptions = {
+ ecmaVersion: 2018,
+ sourceType: 'module',
+ ecmaFeatures: {
+ jsx: true
+ }
+};
+
+// ------------------------------------------------------------------------------
+// Tests
+// ------------------------------------------------------------------------------
+
+const ruleTester = new RuleTester({parserOptions});
+ruleTester.run('jsx-no-namespace', rule, {
+ valid: [{
+ code: ''
+ }, {
+ code: ''
+ }, {
+ code: ''
+ }, {
+ code: ''
+ }, {
+ code: ''
+ }, {
+ code: ''
+ }, {
+ code: ''
+ }, {
+ code: ''
+ }, {
+ code: ''
+ }, {
+ code: ''
+ }, {
+ code: ''
+ }, {
+ code: ''
+ }],
+
+ invalid: [{
+ code: '',
+ errors: [{message: 'JSX component ns:testcomponent must not be in a namespace as React does not support them'}]
+ }, {
+ code: '',
+ errors: [{message: 'JSX component ns:testComponent must not be in a namespace as React does not support them'}]
+ }, {
+ code: '',
+ errors: [{message: 'JSX component ns:test_component must not be in a namespace as React does not support them'}]
+ }, {
+ code: '',
+ errors: [{message: 'JSX component ns:TestComponent must not be in a namespace as React does not support them'}]
+ }, {
+ code: '',
+ errors: [{message: 'JSX component Ns:testcomponent must not be in a namespace as React does not support them'}]
+ }, {
+ code: '',
+ errors: [{message: 'JSX component Ns:testComponent must not be in a namespace as React does not support them'}]
+ }, {
+ code: '',
+ errors: [{message: 'JSX component Ns:test_component must not be in a namespace as React does not support them'}]
+ }, {
+ code: '',
+ errors: [{message: 'JSX component Ns:TestComponent must not be in a namespace as React does not support them'}]
+ }]
+});