diff --git a/cli/eslint.config.mjs b/cli/eslint.config.mjs
index 3f724506a3..9115a1feb7 100644
--- a/cli/eslint.config.mjs
+++ b/cli/eslint.config.mjs
@@ -55,6 +55,7 @@ export default [
       'unicorn/import-style': 'off',
       curly: 2,
       'prettier/prettier': 0,
+      'object-shorthand': ['error', 'always'],
     },
   },
 ];
diff --git a/e2e/eslint.config.mjs b/e2e/eslint.config.mjs
index 9a1bb99598..fd1e8a0af6 100644
--- a/e2e/eslint.config.mjs
+++ b/e2e/eslint.config.mjs
@@ -59,6 +59,7 @@ export default [
       'unicorn/prefer-top-level-await': 'off',
       'unicorn/prefer-event-target': 'off',
       'unicorn/no-thenable': 'off',
+      'object-shorthand': ['error', 'always'],
     },
   },
 ];
diff --git a/server/eslint.config.mjs b/server/eslint.config.mjs
index 638b7b2959..d29b6f7238 100644
--- a/server/eslint.config.mjs
+++ b/server/eslint.config.mjs
@@ -63,6 +63,7 @@ export default [
       '@typescript-eslint/require-await': 'error',
       curly: 2,
       'prettier/prettier': 0,
+      'object-shorthand': ['error', 'always'],
 
       'no-restricted-imports': [
         'error',
diff --git a/server/src/dtos/user-profile.dto.ts b/server/src/dtos/user-profile.dto.ts
index b14662c844..9659fa3965 100644
--- a/server/src/dtos/user-profile.dto.ts
+++ b/server/src/dtos/user-profile.dto.ts
@@ -13,7 +13,7 @@ export class CreateProfileImageResponseDto {
 
 export function mapCreateProfileImageResponse(userId: string, profileImagePath: string): CreateProfileImageResponseDto {
   return {
-    userId: userId,
-    profileImagePath: profileImagePath,
+    userId,
+    profileImagePath,
   };
 }
diff --git a/server/src/repositories/map.repository.ts b/server/src/repositories/map.repository.ts
index 555f1042bb..da4e30d47c 100644
--- a/server/src/repositories/map.repository.ts
+++ b/server/src/repositories/map.repository.ts
@@ -317,7 +317,7 @@ export class MapRepository implements IMapRepository {
     }
 
     const input = createReadStream(filePath);
-    const lineReader = readLine.createInterface({ input: input });
+    const lineReader = readLine.createInterface({ input });
 
     const adminMap = new Map<string, string>();
     for await (const line of lineReader) {
diff --git a/server/src/services/album.service.ts b/server/src/services/album.service.ts
index 1cd5237b7a..b59364af9f 100644
--- a/server/src/services/album.service.ts
+++ b/server/src/services/album.service.ts
@@ -239,7 +239,7 @@ export class AlbumService {
         throw new BadRequestException('User not found');
       }
 
-      await this.albumUserRepository.create({ userId: userId, albumId: id, role });
+      await this.albumUserRepository.create({ userId, albumId: id, role });
       await this.eventRepository.emit('album.invite', { id, userId });
     }
 
diff --git a/server/src/services/auth.service.spec.ts b/server/src/services/auth.service.spec.ts
index d73896edb1..f2fa0c520a 100644
--- a/server/src/services/auth.service.spec.ts
+++ b/server/src/services/auth.service.spec.ts
@@ -46,7 +46,7 @@ const fixtures = {
 };
 
 const oauthUserWithDefaultQuota = {
-  email: email,
+  email,
   name: ' ',
   oauthId: sub,
   quotaSizeInBytes: 1_073_741_824,
@@ -561,7 +561,7 @@ describe('AuthService', () => {
       );
 
       expect(userMock.create).toHaveBeenCalledWith({
-        email: email,
+        email,
         name: ' ',
         oauthId: sub,
         quotaSizeInBytes: null,
@@ -581,7 +581,7 @@ describe('AuthService', () => {
       );
 
       expect(userMock.create).toHaveBeenCalledWith({
-        email: email,
+        email,
         name: ' ',
         oauthId: sub,
         quotaSizeInBytes: 5_368_709_120,
diff --git a/server/src/services/auth.service.ts b/server/src/services/auth.service.ts
index 10cf93b6a4..2b25decc07 100644
--- a/server/src/services/auth.service.ts
+++ b/server/src/services/auth.service.ts
@@ -421,7 +421,7 @@ export class AuthService {
         await this.sessionRepository.update({ id: session.id, updatedAt: new Date() });
       }
 
-      return { user: session.user, session: session };
+      return { user: session.user, session };
     }
 
     throw new UnauthorizedException('Invalid user token');
diff --git a/server/src/services/library.service.ts b/server/src/services/library.service.ts
index c7f82eddea..bcd0a842c7 100644
--- a/server/src/services/library.service.ts
+++ b/server/src/services/library.service.ts
@@ -339,7 +339,7 @@ export class LibraryService {
     const libraryId = job.id;
 
     const assetPagination = usePagination(JOBS_LIBRARY_PAGINATION_SIZE, (pagination) =>
-      this.assetRepository.getAll(pagination, { libraryId: libraryId, withDeleted: true }),
+      this.assetRepository.getAll(pagination, { libraryId, withDeleted: true }),
     );
 
     let assetsFound = false;
@@ -465,7 +465,7 @@ export class LibraryService {
         libraryId: job.id,
         checksum: pathHash,
         originalPath: assetPath,
-        deviceAssetId: deviceAssetId,
+        deviceAssetId,
         deviceId: 'Library Import',
         fileCreatedAt: stats.mtime,
         fileModifiedAt: stats.mtime,
diff --git a/server/src/services/storage-template.service.spec.ts b/server/src/services/storage-template.service.spec.ts
index 92d11eaa12..093cc5b2ff 100644
--- a/server/src/services/storage-template.service.spec.ts
+++ b/server/src/services/storage-template.service.spec.ts
@@ -309,7 +309,7 @@ describe(StorageTemplateService.name, () => {
         entityId: assetStub.image.id,
         pathType: AssetPathType.ORIGINAL,
         oldPath: assetStub.image.originalPath,
-        newPath: newPath,
+        newPath,
       });
       expect(storageMock.rename).toHaveBeenCalledWith(assetStub.image.originalPath, newPath);
       expect(storageMock.copyFile).toHaveBeenCalledWith(assetStub.image.originalPath, newPath);
diff --git a/server/src/services/storage-template.service.ts b/server/src/services/storage-template.service.ts
index 829863e228..9836ad40ac 100644
--- a/server/src/services/storage-template.service.ts
+++ b/server/src/services/storage-template.service.ts
@@ -227,7 +227,7 @@ export class StorageTemplateService {
       const storagePath = this.render(this.template.compiled, {
         asset,
         filename: sanitized,
-        extension: extension,
+        extension,
         albumName,
       });
       const fullPath = path.normalize(path.join(rootPath, storagePath));
diff --git a/server/test/fixtures/asset.stub.ts b/server/test/fixtures/asset.stub.ts
index b8c7e06d82..5ee42224ba 100644
--- a/server/test/fixtures/asset.stub.ts
+++ b/server/test/fixtures/asset.stub.ts
@@ -31,7 +31,7 @@ const files: AssetFileEntity[] = [previewFile, thumbnailFile];
 export const stackStub = (stackId: string, assets: AssetEntity[]): StackEntity => {
   return {
     id: stackId,
-    assets: assets,
+    assets,
     owner: assets[0].owner,
     ownerId: assets[0].ownerId,
     primaryAsset: assets[0],
diff --git a/web/eslint.config.mjs b/web/eslint.config.mjs
index f4aec0e728..f1ba46355f 100644
--- a/web/eslint.config.mjs
+++ b/web/eslint.config.mjs
@@ -87,6 +87,7 @@ export default [
       '@typescript-eslint/no-floating-promises': 'error',
       '@typescript-eslint/no-misused-promises': 'error',
       '@typescript-eslint/require-await': 'error',
+      'object-shorthand': ['error', 'always'],
     },
   },
   {
diff --git a/web/src/lib/components/faces-page/merge-face-selector.svelte b/web/src/lib/components/faces-page/merge-face-selector.svelte
index ea1445a938..71358361ce 100644
--- a/web/src/lib/components/faces-page/merge-face-selector.svelte
+++ b/web/src/lib/components/faces-page/merge-face-selector.svelte
@@ -81,7 +81,7 @@
       const mergedPerson = await getPerson({ id: person.id });
       const count = results.filter(({ success }) => success).length;
       notificationController.show({
-        message: $t('merged_people_count', { values: { count: count } }),
+        message: $t('merged_people_count', { values: { count } }),
         type: NotificationType.Info,
       });
       dispatch('merge', mergedPerson);
diff --git a/web/src/lib/components/photos-page/actions/remove-from-album.svelte b/web/src/lib/components/photos-page/actions/remove-from-album.svelte
index d76ea7b275..2384f95d2e 100644
--- a/web/src/lib/components/photos-page/actions/remove-from-album.svelte
+++ b/web/src/lib/components/photos-page/actions/remove-from-album.svelte
@@ -40,7 +40,7 @@
       const count = results.filter(({ success }) => success).length;
       notificationController.show({
         type: NotificationType.Info,
-        message: $t('assets_removed_count', { values: { count: count } }),
+        message: $t('assets_removed_count', { values: { count } }),
       });
 
       clearSelect();
diff --git a/web/src/lib/components/photos-page/actions/remove-from-shared-link.svelte b/web/src/lib/components/photos-page/actions/remove-from-shared-link.svelte
index 0c785830d0..e838f0813d 100644
--- a/web/src/lib/components/photos-page/actions/remove-from-shared-link.svelte
+++ b/web/src/lib/components/photos-page/actions/remove-from-shared-link.svelte
@@ -45,7 +45,7 @@
 
       notificationController.show({
         type: NotificationType.Info,
-        message: $t('assets_removed_count', { values: { count: count } }),
+        message: $t('assets_removed_count', { values: { count } }),
       });
 
       clearSelect();
diff --git a/web/src/lib/components/photos-page/measure-date-group.svelte b/web/src/lib/components/photos-page/measure-date-group.svelte
index 98e423ae94..f458fe40dd 100644
--- a/web/src/lib/components/photos-page/measure-date-group.svelte
+++ b/web/src/lib/components/photos-page/measure-date-group.svelte
@@ -39,7 +39,7 @@
               if (!heightPending) {
                 const height = element.getBoundingClientRect().height;
                 if (height !== 0) {
-                  $assetStore.updateBucket(bucket.bucketDate, { height: height, measured: true });
+                  $assetStore.updateBucket(bucket.bucketDate, { height, measured: true });
                 }
 
                 onMeasured();
@@ -65,9 +65,7 @@
 <section id="measure-asset-group-by-date" class="flex flex-wrap gap-x-12" use:measure>
   {#each bucket.dateGroups as dateGroup}
     <div id="date-group" data-date-group={dateGroup.date}>
-      <div
-        use:resizeObserver={({ height }) => $assetStore.updateBucketDateGroup(bucket, dateGroup, { height: height })}
-      >
+      <div use:resizeObserver={({ height }) => $assetStore.updateBucketDateGroup(bucket, dateGroup, { height })}>
         <div
           class="flex z-[100] sticky top-[-1px] pt-7 pb-5 h-6 place-items-center text-xs font-medium text-immich-fg bg-immich-bg dark:bg-immich-dark-bg dark:text-immich-dark-fg md:text-sm"
           style:width={dateGroup.geometry.containerWidth + 'px'}
diff --git a/web/src/lib/components/sharedlinks-page/covers/__tests__/share-cover.spec.ts b/web/src/lib/components/sharedlinks-page/covers/__tests__/share-cover.spec.ts
index 2952498b1a..83ca07b40e 100644
--- a/web/src/lib/components/sharedlinks-page/covers/__tests__/share-cover.spec.ts
+++ b/web/src/lib/components/sharedlinks-page/covers/__tests__/share-cover.spec.ts
@@ -50,7 +50,7 @@ describe('ShareCover component', () => {
   it.skip('renders fallback image when asset is not resized', () => {
     const link = sharedLinkFactory.build({ assets: [assetFactory.build()] });
     render(ShareCover, {
-      link: link,
+      link,
       preload: false,
     });
 
diff --git a/web/src/lib/utils/asset-store-task-manager.ts b/web/src/lib/utils/asset-store-task-manager.ts
index 6ca4f057bd..e476738456 100644
--- a/web/src/lib/utils/asset-store-task-manager.ts
+++ b/web/src/lib/utils/asset-store-task-manager.ts
@@ -350,7 +350,7 @@ class IntersectionTask {
     this.internalTaskManager.queueScrollSensitiveTask({
       task,
       cleanup,
-      componentId: componentId,
+      componentId,
       priority: this.priority,
       taskId: this.intersectedKey,
     });
@@ -367,7 +367,7 @@ class IntersectionTask {
     this.internalTaskManager.queueSeparateTask({
       task,
       cleanup,
-      componentId: componentId,
+      componentId,
       taskId: this.separatedKey,
     });
   }
diff --git a/web/src/lib/utils/asset-utils.ts b/web/src/lib/utils/asset-utils.ts
index ce7944b9c9..e309db5ff6 100644
--- a/web/src/lib/utils/asset-utils.ts
+++ b/web/src/lib/utils/asset-utils.ts
@@ -52,7 +52,7 @@ export const addAssetsToAlbum = async (albumId: string, assetIds: string[], show
       timeout: 5000,
       message:
         count > 0
-          ? $t('assets_added_to_album_count', { values: { count: count } })
+          ? $t('assets_added_to_album_count', { values: { count } })
           : $t('assets_were_part_of_album_count', { values: { count: assetIds.length } }),
       button: {
         text: $t('view_album'),
@@ -264,7 +264,7 @@ export const downloadFile = async (asset: AssetResponseDto) => {
 
       downloadBlob(data, filename);
     } catch (error) {
-      handleError(error, $t('errors.error_downloading', { values: { filename: filename } }));
+      handleError(error, $t('errors.error_downloading', { values: { filename } }));
       downloadManager.clear(downloadKey);
     } finally {
       setTimeout(() => downloadManager.clear(downloadKey), 5000);
diff --git a/web/src/lib/utils/person.ts b/web/src/lib/utils/person.ts
index 79f9284d8a..0b30556516 100644
--- a/web/src/lib/utils/person.ts
+++ b/web/src/lib/utils/person.ts
@@ -28,5 +28,5 @@ export const searchNameLocal = (
 };
 
 export const getPersonNameWithHiddenValue = derived(t, ($t) => {
-  return (name: string, isHidden: boolean) => $t('person_hidden', { values: { name: name, hidden: isHidden } });
+  return (name: string, isHidden: boolean) => $t('person_hidden', { values: { name, hidden: isHidden } });
 });
diff --git a/web/src/lib/utils/timeline-util.ts b/web/src/lib/utils/timeline-util.ts
index 3a8f66ee08..541ebea7f5 100644
--- a/web/src/lib/utils/timeline-util.ts
+++ b/web/src/lib/utils/timeline-util.ts
@@ -107,7 +107,7 @@ export function splitBucketIntoDateGroups(bucket: AssetBucket, locale: string |
       heightActual: false,
       intersecting: false,
       geometry: emptyGeometry(),
-      bucket: bucket,
+      bucket,
     };
   });
 }
diff --git a/web/src/routes/(user)/albums/[albumId=id]/[[photos=photos]]/[[assetId=id]]/+page.svelte b/web/src/routes/(user)/albums/[albumId=id]/[[photos=photos]]/[[assetId=id]]/+page.svelte
index 6762e3a1cc..0fa325c6f5 100644
--- a/web/src/routes/(user)/albums/[albumId=id]/[[photos=photos]]/[[assetId=id]]/+page.svelte
+++ b/web/src/routes/(user)/albums/[albumId=id]/[[photos=photos]]/[[assetId=id]]/+page.svelte
@@ -291,7 +291,7 @@
       const count = results.filter(({ success }) => success).length;
       notificationController.show({
         type: NotificationType.Info,
-        message: $t('assets_added_count', { values: { count: count } }),
+        message: $t('assets_added_count', { values: { count } }),
       });
 
       await refreshAlbum();