diff --git a/packages/form/addon/lib/document.js b/packages/form/addon/lib/document.js
index d97cd65a1..4700b0f9f 100644
--- a/packages/form/addon/lib/document.js
+++ b/packages/form/addon/lib/document.js
@@ -188,6 +188,17 @@ export default class Document extends Base {
     });
     documentJexl.addTransform("stringify", (input) => JSON.stringify(input));
     documentJexl.addTransform("flatten", flatten);
+    documentJexl.addTransform("length", (input) => {
+      if (input?.length !== undefined) {
+        // strings, arrays
+        return input.length;
+      } else if (input instanceof Object) {
+        // objects
+        return Object.keys(input).length;
+      }
+
+      return null;
+    });
 
     return documentJexl;
   }
diff --git a/packages/form/tests/unit/lib/document-test.js b/packages/form/tests/unit/lib/document-test.js
index 327f8473d..3405e1f83 100644
--- a/packages/form/tests/unit/lib/document-test.js
+++ b/packages/form/tests/unit/lib/document-test.js
@@ -265,6 +265,25 @@ module("Unit | Library | document", function (hooks) {
     );
   });
 
+  test.each(
+    "it transforms correcty with count transform",
+    [
+      ["['test1', 'test2']|length", 2],
+      ["{key: 1}|length", 1],
+      ["'foobar'|length", 6],
+      ["1|length", null],
+      ["1.1|length", null],
+      ["null|length", null],
+    ],
+    async function (assert, [expression, expected]) {
+      assert.strictEqual(
+        await this.document.jexl.eval(expression),
+        expected,
+        `Expected expression "${expression}" to evaluate to "${expected}"`,
+      );
+    },
+  );
+
   test("computes the correct jexl context (task form)", async function (assert) {
     assert.expect(1);