diff --git a/.github/renovate.json b/.github/renovate.json
index 776c66af68..a1987ca038 100644
--- a/.github/renovate.json
+++ b/.github/renovate.json
@@ -210,10 +210,10 @@
         "eslint-plugin-storybook",
         "eslint-plugin-tailwindcss",
         "husky",
-        "jest-extended",
         "jest-junit",
         "jest-mock-extended",
         "jest-preset-angular",
+        "jest-diff",
         "lint-staged",
         "ts-jest"
       ],
diff --git a/apps/browser/src/vault/popup/components/vault-v2/vault-header/vault-header-v2.component.spec.ts b/apps/browser/src/vault/popup/components/vault-v2/vault-header/vault-header-v2.component.spec.ts
index 38ec6056d1..1f67dd51c2 100644
--- a/apps/browser/src/vault/popup/components/vault-v2/vault-header/vault-header-v2.component.spec.ts
+++ b/apps/browser/src/vault/popup/components/vault-v2/vault-header/vault-header-v2.component.spec.ts
@@ -152,7 +152,7 @@ describe("VaultHeaderV2Component", () => {
   it("defaults the initial state to true", (done) => {
     // The initial value of the `state$` variable above is undefined
     component["initialDisclosureVisibility$"].subscribe((initialVisibility) => {
-      expect(initialVisibility).toBeTrue();
+      expect(initialVisibility).toBe(true);
       done();
     });
 
diff --git a/apps/browser/src/vault/popup/components/vault-v2/view-v2/view-v2.component.spec.ts b/apps/browser/src/vault/popup/components/vault-v2/view-v2/view-v2.component.spec.ts
index 7ee15aa833..526ab2e257 100644
--- a/apps/browser/src/vault/popup/components/vault-v2/view-v2/view-v2.component.spec.ts
+++ b/apps/browser/src/vault/popup/components/vault-v2/view-v2/view-v2.component.spec.ts
@@ -179,7 +179,7 @@ describe("ViewV2Component", () => {
 
       flush(); // Resolve all promises
 
-      expect(doAutofill).toHaveBeenCalledOnce();
+      expect(doAutofill).toHaveBeenCalledTimes(1);
     }));
 
     it('invokes `copy` when action="copy-username"', fakeAsync(() => {
@@ -187,7 +187,7 @@ describe("ViewV2Component", () => {
 
       flush(); // Resolve all promises
 
-      expect(copy).toHaveBeenCalledOnce();
+      expect(copy).toHaveBeenCalledTimes(1);
     }));
 
     it('invokes `copy` when action="copy-password"', fakeAsync(() => {
@@ -195,7 +195,7 @@ describe("ViewV2Component", () => {
 
       flush(); // Resolve all promises
 
-      expect(copy).toHaveBeenCalledOnce();
+      expect(copy).toHaveBeenCalledTimes(1);
     }));
 
     it('invokes `copy` when action="copy-totp"', fakeAsync(() => {
@@ -203,7 +203,7 @@ describe("ViewV2Component", () => {
 
       flush(); // Resolve all promises
 
-      expect(copy).toHaveBeenCalledOnce();
+      expect(copy).toHaveBeenCalledTimes(1);
     }));
 
     it("closes the popout after a load action", fakeAsync(() => {
@@ -218,9 +218,9 @@ describe("ViewV2Component", () => {
 
       flush(); // Resolve all promises
 
-      expect(doAutofill).toHaveBeenCalledOnce();
+      expect(doAutofill).toHaveBeenCalledTimes(1);
       expect(focusSpy).toHaveBeenCalledWith(99);
-      expect(closeSpy).toHaveBeenCalledOnce();
+      expect(closeSpy).toHaveBeenCalledTimes(1);
     }));
   });
 });
diff --git a/apps/browser/src/vault/popup/services/vault-popup-list-filters.service.spec.ts b/apps/browser/src/vault/popup/services/vault-popup-list-filters.service.spec.ts
index 0eb91c6cbe..e1236be08f 100644
--- a/apps/browser/src/vault/popup/services/vault-popup-list-filters.service.spec.ts
+++ b/apps/browser/src/vault/popup/services/vault-popup-list-filters.service.spec.ts
@@ -488,7 +488,7 @@ describe("VaultPopupListFiltersService", () => {
       state$.next(true);
 
       service.filterVisibilityState$.subscribe((filterVisibility) => {
-        expect(filterVisibility).toBeTrue();
+        expect(filterVisibility).toBe(true);
         done();
       });
     });
@@ -496,7 +496,7 @@ describe("VaultPopupListFiltersService", () => {
     it("updates stored filter state", async () => {
       await service.updateFilterVisibility(false);
 
-      expect(update).toHaveBeenCalledOnce();
+      expect(update).toHaveBeenCalledTimes(1);
       // Get callback passed to `update`
       const updateCallback = update.mock.calls[0][0];
       expect(updateCallback()).toBe(false);
diff --git a/libs/admin-console/src/common/collections/services/default-vnext-collection.service.spec.ts b/libs/admin-console/src/common/collections/services/default-vnext-collection.service.spec.ts
index 4aa54429aa..048a473394 100644
--- a/libs/admin-console/src/common/collections/services/default-vnext-collection.service.spec.ts
+++ b/libs/admin-console/src/common/collections/services/default-vnext-collection.service.spec.ts
@@ -91,7 +91,7 @@ describe("DefaultvNextCollectionService", () => {
 
       // Assert emitted values
       expect(result.length).toBe(2);
-      expect(result).toIncludeAllPartialMembers([
+      expect(result).toContainPartialObjects([
         {
           id: collection1.id,
           name: "DEC_NAME_" + collection1.id,
@@ -167,7 +167,7 @@ describe("DefaultvNextCollectionService", () => {
       const result = await firstValueFrom(collectionService.encryptedCollections$(userId));
 
       expect(result.length).toBe(2);
-      expect(result).toIncludeAllPartialMembers([
+      expect(result).toContainPartialObjects([
         {
           id: collection1.id,
           name: makeEncString("ENC_NAME_" + collection1.id),
@@ -205,7 +205,7 @@ describe("DefaultvNextCollectionService", () => {
 
       const result = await firstValueFrom(collectionService.encryptedCollections$(userId));
       expect(result.length).toBe(3);
-      expect(result).toIncludeAllPartialMembers([
+      expect(result).toContainPartialObjects([
         {
           id: collection1.id,
           name: makeEncString("UPDATED_ENC_NAME_" + collection1.id),
@@ -230,7 +230,7 @@ describe("DefaultvNextCollectionService", () => {
 
       const result = await firstValueFrom(collectionService.encryptedCollections$(userId));
       expect(result.length).toBe(1);
-      expect(result).toIncludeAllPartialMembers([
+      expect(result).toContainPartialObjects([
         {
           id: collection1.id,
           name: makeEncString("ENC_NAME_" + collection1.id),
@@ -253,7 +253,7 @@ describe("DefaultvNextCollectionService", () => {
 
       const result = await firstValueFrom(collectionService.encryptedCollections$(userId));
       expect(result.length).toBe(1);
-      expect(result).toIncludeAllPartialMembers([
+      expect(result).toContainPartialObjects([
         {
           id: newCollection3.id,
           name: makeEncString("ENC_NAME_" + newCollection3.id),
diff --git a/libs/admin-console/test.setup.ts b/libs/admin-console/test.setup.ts
index 6be6e7b8dd..8ab102f2cf 100644
--- a/libs/admin-console/test.setup.ts
+++ b/libs/admin-console/test.setup.ts
@@ -1,6 +1,10 @@
 import { webcrypto } from "crypto";
+
+import { addCustomMatchers } from "@bitwarden/common/spec";
 import "jest-preset-angular/setup-jest";
 
+addCustomMatchers();
+
 Object.defineProperty(window, "CSS", { value: null });
 Object.defineProperty(window, "getComputedStyle", {
   value: () => {
diff --git a/libs/admin-console/tsconfig.json b/libs/admin-console/tsconfig.json
index 3d22cb2ec5..4f057fd6af 100644
--- a/libs/admin-console/tsconfig.json
+++ b/libs/admin-console/tsconfig.json
@@ -8,6 +8,6 @@
       "@bitwarden/key-management": ["../key-management/src"]
     }
   },
-  "include": ["src", "spec"],
+  "include": ["src", "spec", "../../libs/common/custom-matchers.d.ts"],
   "exclude": ["node_modules", "dist"]
 }
diff --git a/libs/common/spec/matchers/index.ts b/libs/common/spec/matchers/index.ts
index 44440be5b5..b2e09cc8e9 100644
--- a/libs/common/spec/matchers/index.ts
+++ b/libs/common/spec/matchers/index.ts
@@ -1,16 +1,12 @@
-import * as matchers from "jest-extended";
-
 import { toBeFulfilled, toBeResolved, toBeRejected } from "./promise-fulfilled";
 import { toAlmostEqual } from "./to-almost-equal";
+import { toContainPartialObjects } from "./to-contain-partial-objects";
 import { toEqualBuffer } from "./to-equal-buffer";
 
 export * from "./to-equal-buffer";
 export * from "./to-almost-equal";
 export * from "./promise-fulfilled";
 
-// add all jest-extended matchers
-expect.extend(matchers);
-
 export function addCustomMatchers() {
   expect.extend({
     toEqualBuffer: toEqualBuffer,
@@ -18,6 +14,7 @@ export function addCustomMatchers() {
     toBeFulfilled: toBeFulfilled,
     toBeResolved: toBeResolved,
     toBeRejected: toBeRejected,
+    toContainPartialObjects,
   });
 }
 
@@ -59,4 +56,9 @@ export interface CustomMatchers<R = unknown> {
    * @returns CustomMatcherResult indicating whether or not the test passed
    */
   toBeRejected(withinMs?: number): Promise<R>;
+  /**
+   * Matches if the received array contains all the expected objects using partial matching (expect.objectContaining).
+   * @param expected An array of partial objects that should be contained in the received array.
+   */
+  toContainPartialObjects<T>(expected: Array<T>): R;
 }
diff --git a/libs/common/spec/matchers/to-contain-partial-objects.spec.ts b/libs/common/spec/matchers/to-contain-partial-objects.spec.ts
new file mode 100644
index 0000000000..ab6f90adf1
--- /dev/null
+++ b/libs/common/spec/matchers/to-contain-partial-objects.spec.ts
@@ -0,0 +1,77 @@
+describe("toContainPartialObjects", () => {
+  describe("matches", () => {
+    it("if the array only contains the partial objects", () => {
+      const actual = [
+        {
+          id: 1,
+          name: "foo",
+        },
+        {
+          id: 2,
+          name: "bar",
+        },
+      ];
+
+      const expected = [{ id: 1 }, { id: 2 }];
+
+      expect(actual).toContainPartialObjects(expected);
+    });
+
+    it("if the array contains the partial objects and other objects", () => {
+      const actual = [
+        {
+          id: 1,
+          name: "foo",
+        },
+        {
+          id: 2,
+          name: "bar",
+        },
+        {
+          id: 3,
+          name: "baz",
+        },
+      ];
+
+      const expected = [{ id: 1 }, { id: 2 }];
+
+      expect(actual).toContainPartialObjects(expected);
+    });
+  });
+
+  describe("doesn't match", () => {
+    it("if the array does not contain any partial objects", () => {
+      const actual = [
+        {
+          id: 1,
+          name: "foo",
+        },
+        {
+          id: 2,
+          name: "bar",
+        },
+      ];
+
+      const expected = [{ id: 1, name: "Foo" }];
+
+      expect(actual).not.toContainPartialObjects(expected);
+    });
+
+    it("if the array contains some but not all partial objects", () => {
+      const actual = [
+        {
+          id: 1,
+          name: "foo",
+        },
+        {
+          id: 2,
+          name: "bar",
+        },
+      ];
+
+      const expected = [{ id: 2 }, { id: 3 }];
+
+      expect(actual).not.toContainPartialObjects(expected);
+    });
+  });
+});
diff --git a/libs/common/spec/matchers/to-contain-partial-objects.ts b/libs/common/spec/matchers/to-contain-partial-objects.ts
new file mode 100644
index 0000000000..f072ca6fba
--- /dev/null
+++ b/libs/common/spec/matchers/to-contain-partial-objects.ts
@@ -0,0 +1,31 @@
+import { EOL } from "os";
+
+import { diff } from "jest-diff";
+
+export const toContainPartialObjects: jest.CustomMatcher = function (
+  received: Array<any>,
+  expected: Array<any>,
+) {
+  const matched = this.equals(
+    received,
+    expect.arrayContaining(expected.map((e) => expect.objectContaining(e))),
+  );
+
+  if (matched) {
+    return {
+      message: () =>
+        "Expected the received array NOT to include partial matches for all expected objects." +
+        EOL +
+        diff(expected, received),
+      pass: true,
+    };
+  }
+
+  return {
+    message: () =>
+      "Expected the received array to contain partial matches for all expected objects." +
+      EOL +
+      diff(expected, received),
+    pass: false,
+  };
+};
diff --git a/libs/common/src/tools/cryptography/key-service-legacy-encryptor-provider.spec.ts b/libs/common/src/tools/cryptography/key-service-legacy-encryptor-provider.spec.ts
index 831cad7415..0b60aef491 100644
--- a/libs/common/src/tools/cryptography/key-service-legacy-encryptor-provider.spec.ts
+++ b/libs/common/src/tools/cryptography/key-service-legacy-encryptor-provider.spec.ts
@@ -184,7 +184,7 @@ describe("KeyServiceLegacyEncryptorProvider", () => {
 
       singleUserId$.complete();
 
-      expect(completed).toBeTrue();
+      expect(completed).toBe(true);
     });
 
     it("completes when `userKey$` emits a falsy value after emitting a truthy value", () => {
@@ -199,7 +199,7 @@ describe("KeyServiceLegacyEncryptorProvider", () => {
 
       userKey$.next(null);
 
-      expect(completed).toBeTrue();
+      expect(completed).toBe(true);
     });
 
     it("completes once `dependencies.singleUserId$` emits and `userKey$` completes", () => {
@@ -214,7 +214,7 @@ describe("KeyServiceLegacyEncryptorProvider", () => {
 
       userKey$.complete();
 
-      expect(completed).toBeTrue();
+      expect(completed).toBe(true);
     });
   });
 
@@ -445,7 +445,7 @@ describe("KeyServiceLegacyEncryptorProvider", () => {
 
       singleOrganizationId$.complete();
 
-      expect(completed).toBeTrue();
+      expect(completed).toBe(true);
     });
 
     it("completes when `orgKeys$` emits a falsy value after emitting a truthy value", () => {
@@ -466,7 +466,7 @@ describe("KeyServiceLegacyEncryptorProvider", () => {
       orgKey$.next(OrgRecords);
       orgKey$.next(null);
 
-      expect(completed).toBeTrue();
+      expect(completed).toBe(true);
     });
 
     it("completes once `dependencies.singleOrganizationId$` emits and `userKey$` completes", () => {
@@ -486,7 +486,7 @@ describe("KeyServiceLegacyEncryptorProvider", () => {
 
       orgKey$.complete();
 
-      expect(completed).toBeTrue();
+      expect(completed).toBe(true);
     });
   });
 });
diff --git a/libs/common/src/tools/rx.spec.ts b/libs/common/src/tools/rx.spec.ts
index 9ce147a3ff..2c433fef93 100644
--- a/libs/common/src/tools/rx.spec.ts
+++ b/libs/common/src/tools/rx.spec.ts
@@ -56,7 +56,7 @@ describe("errorOnChange", () => {
 
     source$.complete();
 
-    expect(complete).toBeTrue();
+    expect(complete).toBe(true);
   });
 
   it("errors when the input changes", async () => {
diff --git a/libs/common/src/vault/services/folder/folder.service.spec.ts b/libs/common/src/vault/services/folder/folder.service.spec.ts
index 9fdb4327b9..cc3aa1946c 100644
--- a/libs/common/src/vault/services/folder/folder.service.spec.ts
+++ b/libs/common/src/vault/services/folder/folder.service.spec.ts
@@ -77,7 +77,7 @@ describe("Folder Service", () => {
       const result = await firstValueFrom(folderService.folders$(mockUserId));
 
       expect(result.length).toBe(2);
-      expect(result).toIncludeAllPartialMembers([
+      expect(result).toContainPartialObjects([
         { id: "1", name: makeEncString("ENC_STRING_1") },
         { id: "2", name: makeEncString("ENC_STRING_2") },
       ]);
@@ -98,7 +98,7 @@ describe("Folder Service", () => {
       const result = await firstValueFrom(folderService.folderViews$(mockUserId));
 
       expect(result.length).toBe(3);
-      expect(result).toIncludeAllPartialMembers([
+      expect(result).toContainPartialObjects([
         { id: "1", name: "DEC" },
         { id: "2", name: "DEC" },
         { name: "No Folder" },
diff --git a/package-lock.json b/package-lock.json
index 87e0354f7a..a8f8295251 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -151,7 +151,7 @@
         "html-webpack-injector": "1.1.4",
         "html-webpack-plugin": "5.6.3",
         "husky": "9.1.4",
-        "jest-extended": "4.0.2",
+        "jest-diff": "29.7.0",
         "jest-junit": "16.0.0",
         "jest-mock-extended": "3.0.7",
         "jest-preset-angular": "14.1.1",
@@ -20729,28 +20729,6 @@
         "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
       }
     },
-    "node_modules/jest-extended": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/jest-extended/-/jest-extended-4.0.2.tgz",
-      "integrity": "sha512-FH7aaPgtGYHc9mRjriS0ZEHYM5/W69tLrFTIdzm+yJgeoCmmrSB/luSfMSqWP9O29QWHPEmJ4qmU6EwsZideog==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "jest-diff": "^29.0.0",
-        "jest-get-type": "^29.0.0"
-      },
-      "engines": {
-        "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
-      },
-      "peerDependencies": {
-        "jest": ">=27.2.5"
-      },
-      "peerDependenciesMeta": {
-        "jest": {
-          "optional": true
-        }
-      }
-    },
     "node_modules/jest-get-type": {
       "version": "29.6.3",
       "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz",
diff --git a/package.json b/package.json
index 641a49c4d0..0af1445a8a 100644
--- a/package.json
+++ b/package.json
@@ -111,7 +111,7 @@
     "html-webpack-injector": "1.1.4",
     "html-webpack-plugin": "5.6.3",
     "husky": "9.1.4",
-    "jest-extended": "4.0.2",
+    "jest-diff": "29.7.0",
     "jest-junit": "16.0.0",
     "jest-mock-extended": "3.0.7",
     "jest-preset-angular": "14.1.1",