diff --git a/docs/rules/README.md b/docs/rules/README.md
index b0ed0b69..e9a65bcc 100644
--- a/docs/rules/README.md
+++ b/docs/rules/README.md
@@ -11,6 +11,7 @@ There is no config which enables all rules in this category.
|:--------|:------------|:--:|
| [es/no-bigint](./no-bigint.md) | disallow `bigint` syntax and built-ins. | |
| [es/no-dynamic-import](./no-dynamic-import.md) | disallow `import()` syntax. | |
+| [es/no-export-ns-from](./no-export-ns-from.md) | disallow `export * as ns`. | |
| [es/no-global-this](./no-global-this.md) | disallow the `globalThis` variable. | |
| [es/no-import-meta](./no-import-meta.md) | disallow `new.target` meta property. | |
| [es/no-nullish-coalescing-operators](./no-nullish-coalescing-operators.md) | disallow nullish coalescing operators. | |
diff --git a/docs/rules/no-export-ns-from.md b/docs/rules/no-export-ns-from.md
new file mode 100644
index 00000000..08a2fa46
--- /dev/null
+++ b/docs/rules/no-export-ns-from.md
@@ -0,0 +1,16 @@
+# disallow `export * as ns` (es/no-export-ns-from)
+
+This rule reports ES2020 [`export * as ns`](https://github.com/tc39/proposal-export-ns-from) as errors.
+
+## Examples
+
+⛔ Examples of **incorrect** code for this rule:
+
+
+
+## 📚 References
+
+- [Rule source](https://github.com/mysticatea/eslint-plugin-es/blob/v3.0.1/lib/rules/no-export-ns-from.js)
+- [Test source](https://github.com/mysticatea/eslint-plugin-es/blob/v3.0.1/tests/lib/rules/no-export-ns-from.js)
diff --git a/lib/index.js b/lib/index.js
index 3da71e60..5e9e582f 100644
--- a/lib/index.js
+++ b/lib/index.js
@@ -153,6 +153,7 @@ module.exports = {
"no-destructuring": require("./rules/no-destructuring"),
"no-dynamic-import": require("./rules/no-dynamic-import"),
"no-exponential-operators": require("./rules/no-exponential-operators"),
+ "no-export-ns-from": require("./rules/no-export-ns-from"),
"no-for-of-loops": require("./rules/no-for-of-loops"),
"no-generators": require("./rules/no-generators"),
"no-global-this": require("./rules/no-global-this"),
diff --git a/lib/rules/no-export-ns-from.js b/lib/rules/no-export-ns-from.js
new file mode 100644
index 00000000..55a38fde
--- /dev/null
+++ b/lib/rules/no-export-ns-from.js
@@ -0,0 +1,30 @@
+/**
+ * @author Yosuke Ota
+ * See LICENSE file in root directory for full license.
+ */
+"use strict"
+
+module.exports = {
+ meta: {
+ docs: {
+ description: "disallow `export * as ns`.",
+ category: "ES2020",
+ recommended: false,
+ url:
+ "http://mysticatea.github.io/eslint-plugin-es/rules/no-export-ns-from.html",
+ },
+ fixable: null,
+ messages: {
+ forbidden: "ES2020 'export * as ns' are forbidden.",
+ },
+ schema: [],
+ type: "problem",
+ },
+ create(context) {
+ return {
+ "ExportAllDeclaration[exported!=null]"(node) {
+ context.report({ node, messageId: "forbidden" })
+ },
+ }
+ },
+}
diff --git a/tests/lib/rules/no-export-ns-from.js b/tests/lib/rules/no-export-ns-from.js
new file mode 100644
index 00000000..ed2bcb29
--- /dev/null
+++ b/tests/lib/rules/no-export-ns-from.js
@@ -0,0 +1,35 @@
+/**
+ * @author Yosuke Ota
+ * See LICENSE file in root directory for full license.
+ */
+"use strict"
+
+const RuleTester = require("../../tester")
+const rule = require("../../../lib/rules/no-export-ns-from.js")
+
+if (!RuleTester.isSupported(2020)) {
+ //eslint-disable-next-line no-console
+ console.log("Skip the tests of no-export-ns-from.")
+ return
+}
+
+new RuleTester({
+ parserOptions: { sourceType: "module" },
+}).run("no-export-ns-from", rule, {
+ valid: [
+ 'export * from "mod"',
+ "export default foo",
+ 'export {foo} from "mod"',
+ 'export {foo as bar} from "mod"',
+ 'import * as foo from "mod"',
+ 'import foo from "mod"',
+ 'import {foo} from "mod"',
+ 'import {foo as bar} from "mod"',
+ ],
+ invalid: [
+ {
+ code: 'export * as ns from "mod"',
+ errors: ["ES2020 'export * as ns' are forbidden."],
+ },
+ ],
+})