diff --git a/README.md b/README.md
index 515d97f416..61cc01f8ae 100644
--- a/README.md
+++ b/README.md
@@ -247,6 +247,7 @@ rules in templates can be disabled with eslint directives with mustache or html
| [template-no-obsolete-elements](docs/rules/template-no-obsolete-elements.md) | disallow obsolete HTML elements | | | |
| [template-no-outlet-outside-routes](docs/rules/template-no-outlet-outside-routes.md) | disallow {{outlet}} outside of route templates | | | |
| [template-no-page-title-component](docs/rules/template-no-page-title-component.md) | disallow usage of ember-page-title component | | | |
+| [template-require-strict-mode](docs/rules/template-require-strict-mode.md) | require templates to be in strict mode | | | |
| [template-require-valid-named-block-naming-format](docs/rules/template-require-valid-named-block-naming-format.md) | require valid named block naming format | | 🔧 | |
| [template-self-closing-void-elements](docs/rules/template-self-closing-void-elements.md) | require self-closing on void elements | | 🔧 | |
| [template-simple-modifiers](docs/rules/template-simple-modifiers.md) | require simple modifier syntax | | | |
diff --git a/docs/rules/template-require-strict-mode.md b/docs/rules/template-require-strict-mode.md
new file mode 100644
index 0000000000..cf76e9def5
--- /dev/null
+++ b/docs/rules/template-require-strict-mode.md
@@ -0,0 +1,57 @@
+# ember/template-require-strict-mode
+
+> **HBS Only**: This rule applies to classic `.hbs` template files only (loose mode). It is not relevant for `gjs`/`gts` files (strict mode), where these patterns cannot occur.
+
+
+
+Require templates to be in strict mode.
+
+Ember's Polaris edition component authoring format is template tag, which makes
+templates follow "strict mode" semantics.
+
+This rule requires all templates to use strict mode (template tag). Effectively this
+means you may only have template content in `.gjs`/`.gts` files, not in `.hbs` or
+`.js`/`.ts`.
+
+## Examples
+
+This rule **forbids** the following:
+
+```hbs
+// button.hbs
+
+```
+
+```js
+// button-test.js
+import { hbs } from 'ember-cli-htmlbars';
+
+test('it renders', async (assert) => {
+ await render(hbs``);
+ // ...
+});
+```
+
+This rule **allows** the following:
+
+```gjs
+// button.gjs
+
+
+
+```
+
+```gjs
+// button-test.gjs
+import { Button } from 'ember-awesome-button';
+
+test('it renders', async (assert) => {
+ await render();
+ // ..
+});
+```
+
+## References
+
+- [Template Tag Guide](https://guides.emberjs.com/release/components/template-tag-format/)
+- [Strict Mode RFC](https://rfcs.emberjs.com/id/0496-handlebars-strict-mode/)
diff --git a/lib/rules/template-require-strict-mode.js b/lib/rules/template-require-strict-mode.js
new file mode 100644
index 0000000000..9e6bfccb06
--- /dev/null
+++ b/lib/rules/template-require-strict-mode.js
@@ -0,0 +1,44 @@
+const ERROR_MESSAGE =
+ 'Templates are required to be in strict mode. Consider refactoring to template tag format.';
+
+function isStrictModeFile(filePath) {
+ return filePath?.endsWith('.gjs') || filePath?.endsWith('.gts');
+}
+
+/** @type {import('eslint').Rule.RuleModule} */
+module.exports = {
+ meta: {
+ type: 'suggestion',
+ docs: {
+ description: 'require templates to be in strict mode',
+ category: 'Best Practices',
+ recommended: false,
+ url: 'https://github.com/ember-cli/eslint-plugin-ember/tree/master/docs/rules/template-require-strict-mode.md',
+ templateMode: 'loose',
+ },
+ fixable: null,
+ schema: [],
+ messages: {},
+ originallyFrom: {
+ name: 'ember-template-lint',
+ rule: 'lib/rules/require-strict-mode.js',
+ docs: 'docs/rule/require-strict-mode.md',
+ tests: 'test/unit/rules/require-strict-mode-test.js',
+ },
+ },
+
+ create(context) {
+ const filePath = context.getFilename ? context.getFilename() : context.filename;
+
+ return {
+ 'GlimmerTemplate:exit'(node) {
+ if (!isStrictModeFile(filePath)) {
+ context.report({
+ node,
+ message: ERROR_MESSAGE,
+ });
+ }
+ },
+ };
+ },
+};
diff --git a/tests/lib/rules/template-require-strict-mode.js b/tests/lib/rules/template-require-strict-mode.js
new file mode 100644
index 0000000000..994b573060
--- /dev/null
+++ b/tests/lib/rules/template-require-strict-mode.js
@@ -0,0 +1,70 @@
+const rule = require('../../../lib/rules/template-require-strict-mode');
+const RuleTester = require('eslint').RuleTester;
+
+const ruleTester = new RuleTester({
+ parser: require.resolve('ember-eslint-parser'),
+ parserOptions: { ecmaVersion: 2022, sourceType: 'module' },
+});
+
+ruleTester.run('template-require-strict-mode', rule, {
+ valid: [
+ {
+ filename: 'hello.gjs',
+ code: 'hello',
+ },
+ {
+ filename: 'hello.gts',
+ code: 'hello',
+ },
+ ],
+ invalid: [
+ {
+ filename: 'hello.hbs',
+ code: '