diff --git a/README.md b/README.md
index 299aaf45c0..7f28e984ba 100644
--- a/README.md
+++ b/README.md
@@ -180,6 +180,7 @@ rules in templates can be disabled with eslint directives with mustache or html
| :------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------- | :- | :- | :- |
| [no-attrs-in-components](docs/rules/no-attrs-in-components.md) | disallow usage of `this.attrs` in components | ✅ | | |
| [no-attrs-snapshot](docs/rules/no-attrs-snapshot.md) | disallow use of attrs snapshot in the `didReceiveAttrs` and `didUpdateAttrs` component hooks | ✅ | | |
+| [no-builtin-form-components](docs/rules/no-builtin-form-components.md) | disallow usage of built-in form components | | | |
| [no-classic-components](docs/rules/no-classic-components.md) | enforce using Glimmer components | ✅ | | |
| [no-component-lifecycle-hooks](docs/rules/no-component-lifecycle-hooks.md) | disallow usage of "classic" ember component lifecycle hooks. Render modifiers or custom functional modifiers should be used instead. | ✅ | | |
| [no-on-calls-in-components](docs/rules/no-on-calls-in-components.md) | disallow usage of `on` to call lifecycle hooks in components | ✅ | | |
diff --git a/docs/rules/no-builtin-form-components.md b/docs/rules/no-builtin-form-components.md
new file mode 100644
index 0000000000..5296fd2542
--- /dev/null
+++ b/docs/rules/no-builtin-form-components.md
@@ -0,0 +1,93 @@
+# ember/no-builtin-form-components
+
+
+
+This rule disallows the use of Ember's built-in form components (`Input` and `Textarea`) from `@ember/component` and encourages using native HTML elements instead.
+
+## Rule Details
+
+Ember's built-in form components (`Input` and `Textarea`) were designed to bridge the gap between classic HTML form elements and Ember's component system. However, as Ember has evolved, using native HTML elements with modifiers has become the preferred approach for several reasons:
+
+- Native HTML elements have better accessibility support
+- They provide a more consistent developer experience with standard web development
+- They have better performance characteristics
+- They avoid the extra abstraction layer that the built-in components provide
+
+This rule helps identify where these built-in form components are being used so they can be replaced with native HTML elements.
+
+## Examples
+
+Examples of **incorrect** code for this rule:
+
+```js
+import { Input } from '@ember/component';
+```
+
+```js
+import { Textarea } from '@ember/component';
+```
+
+```js
+import { Input as EmberInput, Textarea as EmberTextarea } from '@ember/component';
+```
+
+Examples of **correct** code for this rule:
+
+```hbs
+
+
+
+
+
+```
+
+## Migration
+
+### Input Component
+
+Replace:
+
+```hbs
+
+```
+
+With:
+
+```hbs
+
+```
+
+### Textarea Component
+
+Replace:
+
+```hbs
+
+```
+
+With:
+
+```hbs
+
+```
+
+## References
+
+- [Ember Input Component API](https://api.emberjs.com/ember/release/classes/Input)
+- [Ember Textarea Component API](https://api.emberjs.com/ember/release/classes/Textarea)
+- [Ember Octane Modifier RFC](https://emberjs.github.io/rfcs/0373-element-modifiers.html)
diff --git a/lib/rules/no-builtin-form-components.js b/lib/rules/no-builtin-form-components.js
new file mode 100644
index 0000000000..06554ccf7a
--- /dev/null
+++ b/lib/rules/no-builtin-form-components.js
@@ -0,0 +1,48 @@
+'use strict';
+
+const { getImportIdentifier } = require('../utils/import');
+
+const ERROR_MESSAGE = 'Do not use built-in form components. Use native HTML elements instead.';
+const DISALLOWED_IMPORTS = new Set(['Input', 'Textarea']);
+
+/** @type {import('eslint').Rule.RuleModule} */
+module.exports = {
+ meta: {
+ type: 'suggestion',
+ docs: {
+ description: 'disallow usage of built-in form components',
+ category: 'Components',
+ recommended: false,
+ url: 'https://github.com/ember-cli/eslint-plugin-ember/tree/master/docs/rules/no-builtin-form-components.md',
+ },
+ fixable: null,
+ schema: [],
+ },
+
+ ERROR_MESSAGE,
+
+ create(context) {
+ const report = function (node) {
+ context.report({ node, message: ERROR_MESSAGE });
+ };
+
+ return {
+ ImportDeclaration(node) {
+ if (node.source.value === '@ember/component') {
+ // Check for named imports like: import { Input } from '@ember/component';
+ const namedImports = node.specifiers.filter(
+ (specifier) =>
+ specifier.type === 'ImportSpecifier' &&
+ DISALLOWED_IMPORTS.has(specifier.imported.name)
+ );
+
+ if (namedImports.length > 0) {
+ for (const specifier of namedImports) {
+ report(specifier);
+ }
+ }
+ }
+ },
+ };
+ },
+};
diff --git a/tests/lib/rules/no-builtin-form-components.js b/tests/lib/rules/no-builtin-form-components.js
new file mode 100644
index 0000000000..22a8b07d00
--- /dev/null
+++ b/tests/lib/rules/no-builtin-form-components.js
@@ -0,0 +1,86 @@
+'use strict';
+
+//------------------------------------------------------------------------------
+// Requirements
+//------------------------------------------------------------------------------
+
+const rule = require('../../../lib/rules/no-builtin-form-components');
+const RuleTester = require('eslint').RuleTester;
+
+//------------------------------------------------------------------------------
+// Tests
+//------------------------------------------------------------------------------
+
+const { ERROR_MESSAGE } = rule;
+const parserOptions = {
+ ecmaVersion: 2022,
+ sourceType: 'module',
+};
+const ruleTester = new RuleTester({ parserOptions });
+
+ruleTester.run('no-builtin-form-components', rule, {
+ valid: [
+ "import Component from '@ember/component';",
+ "import { setComponentTemplate } from '@ember/component';",
+ "import { helper } from '@ember/component/helper';",
+ "import { Input } from 'custom-component';",
+ "import { Textarea } from 'custom-component';",
+ ],
+
+ invalid: [
+ {
+ code: "import { Input } from '@ember/component';",
+ output: null,
+ errors: [
+ {
+ message: ERROR_MESSAGE,
+ type: 'ImportSpecifier',
+ },
+ ],
+ },
+ {
+ code: "import { Textarea } from '@ember/component';",
+ output: null,
+ errors: [
+ {
+ message: ERROR_MESSAGE,
+ type: 'ImportSpecifier',
+ },
+ ],
+ },
+ {
+ code: "import { Input, Textarea } from '@ember/component';",
+ output: null,
+ errors: [
+ {
+ message: ERROR_MESSAGE,
+ type: 'ImportSpecifier',
+ },
+ {
+ message: ERROR_MESSAGE,
+ type: 'ImportSpecifier',
+ },
+ ],
+ },
+ {
+ code: "import { Input as EmberInput } from '@ember/component';",
+ output: null,
+ errors: [
+ {
+ message: ERROR_MESSAGE,
+ type: 'ImportSpecifier',
+ },
+ ],
+ },
+ {
+ code: "import { Textarea as EmberTextarea } from '@ember/component';",
+ output: null,
+ errors: [
+ {
+ message: ERROR_MESSAGE,
+ type: 'ImportSpecifier',
+ },
+ ],
+ },
+ ],
+});