diff --git a/.changeset/breezy-beers-peel.md b/.changeset/breezy-beers-peel.md
new file mode 100644
index 000000000000..dc8739fe74d1
--- /dev/null
+++ b/.changeset/breezy-beers-peel.md
@@ -0,0 +1,5 @@
+---
+'@astrojs/image': patch
+---
+
+Fixes use of image worker pool in SSR environments
diff --git a/packages/integrations/image/src/index.ts b/packages/integrations/image/src/index.ts
index e3770d5e91e9..80d87fbd130c 100644
--- a/packages/integrations/image/src/index.ts
+++ b/packages/integrations/image/src/index.ts
@@ -11,6 +11,12 @@ export { getPicture } from './lib/get-picture.js';
 
 const PKG_NAME = '@astrojs/image';
 const ROUTE_PATTERN = '/_image';
+const UNSUPPORTED_ADAPTERS = new Set([
+	'@astrojs/cloudflare',
+	'@astrojs/deno',
+	'@astrojs/netlify/edge-functions',
+	'@astrojs/vercel/edge'
+]);
 
 interface BuildConfig {
 	client: URL;
@@ -100,6 +106,11 @@ export default function integration(options: IntegrationOptions = {}): AstroInte
 				_buildConfig = config.build;
 			},
 			'astro:build:start': ({ buildConfig }) => {
+				const adapterName = _config.adapter?.name;
+				if(adapterName && UNSUPPORTED_ADAPTERS.has(adapterName)) {
+					throw new Error(`@astrojs/image is not supported with the ${adapterName} adapter. Please choose a Node.js compatible adapter.`);
+				}
+
 				// Backwards compat
 				if (needsBuildConfig) {
 					_buildConfig = buildConfig;
diff --git a/packages/integrations/image/src/loaders/squoosh.ts b/packages/integrations/image/src/loaders/squoosh.ts
index 87d6e26ec1ad..5d71cdb7fbce 100644
--- a/packages/integrations/image/src/loaders/squoosh.ts
+++ b/packages/integrations/image/src/loaders/squoosh.ts
@@ -3,11 +3,12 @@ import { red } from 'kleur/colors';
 import { error } from '../utils/logger.js';
 import { metadata } from '../utils/metadata.js';
 import { isRemoteImage } from '../utils/paths.js';
-import { processBuffer } from '../vendor/squoosh/image-pool.js';
 import type { Operation } from '../vendor/squoosh/image.js';
 import type { OutputFormat, TransformOptions } from './index.js';
 import { BaseSSRService } from './index.js';
 
+const imagePoolModulePromise = import('../vendor/squoosh/image-pool.js');
+
 class SquooshService extends BaseSSRService {
 	async processAvif(image: any, transform: TransformOptions) {
 		const encodeOptions = transform.quality
@@ -112,7 +113,7 @@ class SquooshService extends BaseSSRService {
 			});
 			throw new Error(`Unknown image output: "${transform.format}" used for ${transform.src}`);
 		}
-
+		const { processBuffer } = await imagePoolModulePromise;
 		const data = await processBuffer(inputBuffer, operations, transform.format, transform.quality);
 
 		return {
diff --git a/packages/integrations/image/src/vendor/squoosh/image-pool.ts b/packages/integrations/image/src/vendor/squoosh/image-pool.ts
index d29245fb40dc..e19215397c89 100644
--- a/packages/integrations/image/src/vendor/squoosh/image-pool.ts
+++ b/packages/integrations/image/src/vendor/squoosh/image-pool.ts
@@ -1,5 +1,6 @@
 import { isMainThread } from 'node:worker_threads';
 import { cpus } from 'os';
+import { fileURLToPath } from 'url';
 import type { OutputFormat } from '../../loaders/index.js';
 import execOnce from '../../utils/execOnce.js';
 import WorkerPool from '../../utils/workerPool.js';
@@ -12,7 +13,7 @@ const getWorker = execOnce(
 			// There will be at most 7 workers needed since each worker will take
       // at least 1 operation type.
       Math.max(1, Math.min(cpus().length - 1, 7)),
-			'./node_modules/@astrojs/image/dist/vendor/squoosh/image-pool.js'
+			fileURLToPath(import.meta.url)
 		);
 	}
 )
diff --git a/packages/integrations/image/src/vite-plugin-astro-image.ts b/packages/integrations/image/src/vite-plugin-astro-image.ts
index 04f2303414d7..ee06b0d5ca35 100644
--- a/packages/integrations/image/src/vite-plugin-astro-image.ts
+++ b/packages/integrations/image/src/vite-plugin-astro-image.ts
@@ -113,6 +113,27 @@ export function createPlugin(config: AstroConfig, options: Required<IntegrationO
 				return next();
 			});
 		},
+		outputOptions(outputOptions) {
+      if(resolvedConfig.build.ssr) {
+				// Build the image-pool chunk to the top-level and not inside of a chunks/
+				// folder. This is because the wasm is built at the top-level and this makes
+				// it accessible from the pool worker.
+        const chunkFileNames = outputOptions.chunkFileNames;
+        outputOptions.chunkFileNames = (chunk) => {
+          for(const name of Object.keys(chunk.modules)) {
+            if(name.endsWith('vendor/squoosh/image-pool.js')) {
+              return '[name].[hash].mjs';
+            }
+          }
+
+					if(typeof chunkFileNames === 'function') {
+						return chunkFileNames.call(this, chunk);
+					}
+
+          return  chunkFileNames!;
+        };
+      }
+		},
 		async renderChunk(code) {
 			const assetUrlRE = /__ASTRO_IMAGE_ASSET__([a-z\d]{8})__(?:_(.*?)__)?/g;