diff --git a/apps/test-bot/commandkit.config.ts b/apps/test-bot/commandkit.config.ts
index 05d14f16..b90ef5d3 100644
--- a/apps/test-bot/commandkit.config.ts
+++ b/apps/test-bot/commandkit.config.ts
@@ -1,15 +1,21 @@
-import { defineConfig } from 'commandkit/config';
-import { legacy } from '@commandkit/legacy';
+import { defineConfig, noBuildOnly } from 'commandkit/config';
 import { i18n } from '@commandkit/i18n';
 import { devtools } from '@commandkit/devtools';
 import { cache } from '@commandkit/cache';
 import { ai } from '@commandkit/ai';
 import { tasks } from '@commandkit/tasks';
 
+const setup = noBuildOnly(() => {
+  setInterval(() => {
+    console.log(`Hello from ${process.pid}`);
+  }, 1000);
+});
+
+setup();
+
 export default defineConfig({
   plugins: [
     i18n(),
-    // legacy({ skipBuiltInValidations: true }),
     devtools(),
     cache(),
     ai(),
diff --git a/apps/website/docs/api-reference/commandkit/functions/build-only.mdx b/apps/website/docs/api-reference/commandkit/functions/build-only.mdx
new file mode 100644
index 00000000..300448f7
--- /dev/null
+++ b/apps/website/docs/api-reference/commandkit/functions/build-only.mdx
@@ -0,0 +1,39 @@
+---
+title: "BuildOnly"
+isDefaultIndex: false
+generated: true
+---
+
+import MemberInfo from '@site/src/components/MemberInfo';
+import GenerationInfo from '@site/src/components/GenerationInfo';
+import MemberDescription from '@site/src/components/MemberDescription';
+
+
+
+
+## buildOnly
+
+
+
+Creates a function from the given function that runs only in build mode.
+
+
+
+*Example*
+
+```ts
+const buildOnlyFn = buildOnly(() => {
+  console.log('This function runs only in build mode');
+});
+buildOnlyFn(); // This will log the message only in build mode
+```
+
+```ts title="Signature"
+function buildOnly any>(fn: T): T
+```
+Parameters
+
+### fn
+
+
+
diff --git a/apps/website/docs/api-reference/commandkit/functions/create-proxy.mdx b/apps/website/docs/api-reference/commandkit/functions/create-proxy.mdx
index f050d3aa..08206009 100644
--- a/apps/website/docs/api-reference/commandkit/functions/create-proxy.mdx
+++ b/apps/website/docs/api-reference/commandkit/functions/create-proxy.mdx
@@ -13,7 +13,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## createProxy
 
-
+
 
 Creates a simple proxy object that mirrors the target object.
 
diff --git a/apps/website/docs/api-reference/commandkit/functions/debounce.mdx b/apps/website/docs/api-reference/commandkit/functions/debounce.mdx
index 6fade3b4..e90a1eb1 100644
--- a/apps/website/docs/api-reference/commandkit/functions/debounce.mdx
+++ b/apps/website/docs/api-reference/commandkit/functions/debounce.mdx
@@ -13,7 +13,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## debounce
 
-
+
 
 Debounces a function.
 
diff --git a/apps/website/docs/api-reference/commandkit/functions/defer.mdx b/apps/website/docs/api-reference/commandkit/functions/defer.mdx
index 6005df9e..0b8d627d 100644
--- a/apps/website/docs/api-reference/commandkit/functions/defer.mdx
+++ b/apps/website/docs/api-reference/commandkit/functions/defer.mdx
@@ -13,7 +13,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## defer
 
-
+
 
 Defers the execution of a function.
 
diff --git a/apps/website/docs/api-reference/commandkit/functions/dev-only.mdx b/apps/website/docs/api-reference/commandkit/functions/dev-only.mdx
index 9b3896b1..c3c9bf65 100644
--- a/apps/website/docs/api-reference/commandkit/functions/dev-only.mdx
+++ b/apps/website/docs/api-reference/commandkit/functions/dev-only.mdx
@@ -13,7 +13,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## devOnly
 
-
+
 
 Creates a function from the given function that runs only in development mode.
 
diff --git a/apps/website/docs/api-reference/commandkit/functions/find-app-directory.mdx b/apps/website/docs/api-reference/commandkit/functions/find-app-directory.mdx
index e5c4a8f2..a802237d 100644
--- a/apps/website/docs/api-reference/commandkit/functions/find-app-directory.mdx
+++ b/apps/website/docs/api-reference/commandkit/functions/find-app-directory.mdx
@@ -13,7 +13,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## findAppDirectory
 
-
+
 
 Returns the path to the app directory.
 
diff --git a/apps/website/docs/api-reference/commandkit/functions/get-current-directory.mdx b/apps/website/docs/api-reference/commandkit/functions/get-current-directory.mdx
index 7e97f24a..344110cf 100644
--- a/apps/website/docs/api-reference/commandkit/functions/get-current-directory.mdx
+++ b/apps/website/docs/api-reference/commandkit/functions/get-current-directory.mdx
@@ -13,7 +13,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## getCurrentDirectory
 
-
+
 
 Returns the current working directory of the CommandKit application.
 This is typically the directory where the source code is located.
diff --git a/apps/website/docs/api-reference/commandkit/functions/get-source-directories.mdx b/apps/website/docs/api-reference/commandkit/functions/get-source-directories.mdx
index 269fb66c..279fa99e 100644
--- a/apps/website/docs/api-reference/commandkit/functions/get-source-directories.mdx
+++ b/apps/website/docs/api-reference/commandkit/functions/get-source-directories.mdx
@@ -13,7 +13,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## getSourceDirectories
 
-
+
 
 Returns the possible source directories for the CommandKit application.
 This includes the `src`, `.commandkit`, and the distribution directory.
diff --git a/apps/website/docs/api-reference/commandkit/functions/json-serialize.mdx b/apps/website/docs/api-reference/commandkit/functions/json-serialize.mdx
index b76aa015..69780f82 100644
--- a/apps/website/docs/api-reference/commandkit/functions/json-serialize.mdx
+++ b/apps/website/docs/api-reference/commandkit/functions/json-serialize.mdx
@@ -13,7 +13,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## JsonSerialize
 
-
+
 
 Serializes a value to JSON.
 
diff --git a/apps/website/docs/api-reference/commandkit/functions/no-build-only.mdx b/apps/website/docs/api-reference/commandkit/functions/no-build-only.mdx
new file mode 100644
index 00000000..2c9af655
--- /dev/null
+++ b/apps/website/docs/api-reference/commandkit/functions/no-build-only.mdx
@@ -0,0 +1,39 @@
+---
+title: "NoBuildOnly"
+isDefaultIndex: false
+generated: true
+---
+
+import MemberInfo from '@site/src/components/MemberInfo';
+import GenerationInfo from '@site/src/components/GenerationInfo';
+import MemberDescription from '@site/src/components/MemberDescription';
+
+
+
+
+## noBuildOnly
+
+
+
+Creates a function from the given function that runs only outside of build mode.
+
+
+
+*Example*
+
+```ts
+const noBuildOnlyFn = noBuildOnly(() => {
+  console.log('This function runs only outside of build mode');
+});
+noBuildOnlyFn(); // This will log the message only outside of build mode
+```
+
+```ts title="Signature"
+function noBuildOnly any>(fn: T): T
+```
+Parameters
+
+### fn
+
+
+
diff --git a/apps/website/docs/api-reference/commandkit/interfaces/simple-proxy.mdx b/apps/website/docs/api-reference/commandkit/interfaces/simple-proxy.mdx
index dc55483c..979f81c5 100644
--- a/apps/website/docs/api-reference/commandkit/interfaces/simple-proxy.mdx
+++ b/apps/website/docs/api-reference/commandkit/interfaces/simple-proxy.mdx
@@ -13,7 +13,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## SimpleProxy
 
-
+
 
 Represents a simple proxy object that mirrors a target object.
 
diff --git a/apps/website/docs/api-reference/commandkit/types/hmrevent-type.mdx b/apps/website/docs/api-reference/commandkit/types/hmrevent-type.mdx
index d42b1534..de039772 100644
--- a/apps/website/docs/api-reference/commandkit/types/hmrevent-type.mdx
+++ b/apps/website/docs/api-reference/commandkit/types/hmrevent-type.mdx
@@ -13,7 +13,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## HMREventType
 
-
+
 
 The type for HMR events.
 
diff --git a/apps/website/docs/api-reference/commandkit/variables/commandkit_bootstrap_mode.mdx b/apps/website/docs/api-reference/commandkit/variables/commandkit_bootstrap_mode.mdx
index c058b3f5..a608ca7d 100644
--- a/apps/website/docs/api-reference/commandkit/variables/commandkit_bootstrap_mode.mdx
+++ b/apps/website/docs/api-reference/commandkit/variables/commandkit_bootstrap_mode.mdx
@@ -13,7 +13,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## COMMANDKIT_BOOTSTRAP_MODE
 
-
+
 
 The current bootstrap mode of CommandKit.
 This can be 'development' or 'production'.
diff --git a/apps/website/docs/api-reference/commandkit/variables/hmrevent-type.mdx b/apps/website/docs/api-reference/commandkit/variables/hmrevent-type.mdx
index 36b58698..f8ac7bb1 100644
--- a/apps/website/docs/api-reference/commandkit/variables/hmrevent-type.mdx
+++ b/apps/website/docs/api-reference/commandkit/variables/hmrevent-type.mdx
@@ -13,7 +13,7 @@ import MemberDescription from '@site/src/components/MemberDescription';
 
 ## HMREventType
 
-
+
 
 Types of Hot Module Replacement events
 
diff --git a/apps/website/docs/guide/05-official-plugins/08-commandkit-tasks.mdx b/apps/website/docs/guide/05-official-plugins/08-commandkit-tasks.mdx
index a19c2778..ed840a3a 100644
--- a/apps/website/docs/guide/05-official-plugins/08-commandkit-tasks.mdx
+++ b/apps/website/docs/guide/05-official-plugins/08-commandkit-tasks.mdx
@@ -130,30 +130,42 @@ const driver = new BullMQDriver({
 ### Environment-specific configuration
 
 ```ts
+import { COMMANDKIT_IS_DEV } from 'commandkit';
+import { defineConfig, noBuildOnly } from 'commandkit/config';
 import { tasks } from '@commandkit/tasks';
 import { SQLiteDriver } from '@commandkit/tasks/sqlite';
 import { BullMQDriver } from '@commandkit/tasks/bullmq';
 import { setDriver } from '@commandkit/tasks';
-import { COMMANDKIT_IS_DEV } from 'commandkit';
 
-// Choose driver based on environment
-if (COMMANDKIT_IS_DEV) {
-  setDriver(new SQLiteDriver('./tasks.db'));
-} else {
-  setDriver(
-    new BullMQDriver({
-      host: process.env.REDIS_HOST || 'localhost',
-      port: parseInt(process.env.REDIS_PORT || '6379'),
-      password: process.env.REDIS_PASSWORD,
-    }),
-  );
-}
+// set up the driver in non-build processes only
+const setupDriver = noBuildOnly(() => {
+  // Choose driver based on environment
+  if (COMMANDKIT_IS_DEV) {
+    setDriver(new SQLiteDriver('./tasks.db'));
+  } else {
+    setDriver(
+      new BullMQDriver({
+        host: process.env.REDIS_HOST || 'localhost',
+        port: parseInt(process.env.REDIS_PORT || '6379'),
+        password: process.env.REDIS_PASSWORD,
+      }),
+    );
+  }
+});
+
+setupDriver();
 
-export default {
+export default defineConfig({
   plugins: [tasks()],
-};
+});
 ```
 
+:::warning
+Avoid loading the code that keeps the event loop alive inside the build process.
+Otherwise the build command will never exit. Use the helper functions such as `buildOnly()` or `noBuildOnly()`
+to conditionally load the code in appropriate places.
+:::
+
 ## Creating your first task
 
 Create a file in `src/app/tasks/` to define your tasks:
diff --git a/packages/commandkit/config.cjs b/packages/commandkit/config.cjs
index c14b2d66..76bdc6eb 100644
--- a/packages/commandkit/config.cjs
+++ b/packages/commandkit/config.cjs
@@ -1,5 +1,8 @@
 const { defineConfig } = require('./dist/config/config.js');
+const { buildOnly, noBuildOnly } = require('./dist/utils/utilities.js');
 
 module.exports = {
   defineConfig,
+  buildOnly,
+  noBuildOnly,
 };
diff --git a/packages/commandkit/config.d.ts b/packages/commandkit/config.d.ts
index ac4bc397..275e9f1e 100644
--- a/packages/commandkit/config.d.ts
+++ b/packages/commandkit/config.d.ts
@@ -1 +1,2 @@
 export { defineConfig, CommandKitConfiguration as Config } from './dist/index';
+export { buildOnly, noBuildOnly } from './dist/utils/utilities';
diff --git a/packages/commandkit/src/cli/development.ts b/packages/commandkit/src/cli/development.ts
index 1c27060e..10130094 100644
--- a/packages/commandkit/src/cli/development.ts
+++ b/packages/commandkit/src/cli/development.ts
@@ -54,6 +54,7 @@ const isEventSource = (p: string) =>
  */
 export async function bootstrapDevelopmentServer(configPath?: string) {
   process.env.COMMANDKIT_BOOTSTRAP_MODE = 'development';
+  process.env.COMMANDKIT_INTERNAL_IS_CLI_PROCESS = 'true';
   const start = performance.now();
   const cwd = configPath || COMMANDKIT_CWD;
   const configPaths = getPossibleConfigPaths(cwd);
diff --git a/packages/commandkit/src/cli/env.ts b/packages/commandkit/src/cli/env.ts
index cd4cf96e..9c6c039a 100644
--- a/packages/commandkit/src/cli/env.ts
+++ b/packages/commandkit/src/cli/env.ts
@@ -6,6 +6,8 @@ export function DevEnv(_static = false) {
   const common = {
     NODE_ENV: 'development',
     COMMANDKIT_IS_DEV: 'true',
+    COMMANDKIT_INTERNAL_IS_CLI_PROCESS: 'false',
+    COMMANDKIT_IS_BUILD: 'false',
   };
 
   if (_static) return Object.assign({}, common);
@@ -21,6 +23,8 @@ export function ProdEnv(_static = false) {
   const common = {
     NODE_ENV: 'production',
     COMMANDKIT_IS_DEV: 'false',
+    COMMANDKIT_INTERNAL_IS_CLI_PROCESS: 'false',
+    COMMANDKIT_IS_BUILD: 'false',
   };
 
   if (_static) return Object.assign({}, common);
diff --git a/packages/commandkit/src/cli/production.ts b/packages/commandkit/src/cli/production.ts
index b78472e2..cb1ed460 100644
--- a/packages/commandkit/src/cli/production.ts
+++ b/packages/commandkit/src/cli/production.ts
@@ -32,6 +32,8 @@ export async function bootstrapProductionServer(configPath?: string) {
  */
 export async function createProductionBuild(configPath?: string) {
   process.env.COMMANDKIT_BOOTSTRAP_MODE = 'production';
+  process.env.COMMANDKIT_INTERNAL_IS_CLI_PROCESS = 'true';
+  process.env.COMMANDKIT_IS_BUILD ??= 'true';
   const cwd = configPath || COMMANDKIT_CWD;
   const config = await loadConfigFile(cwd);
 
diff --git a/packages/commandkit/src/utils/constants.ts b/packages/commandkit/src/utils/constants.ts
index a71b06d8..cd613298 100644
--- a/packages/commandkit/src/utils/constants.ts
+++ b/packages/commandkit/src/utils/constants.ts
@@ -18,6 +18,18 @@ export const COMMANDKIT_IS_CLI = process.env.COMMANDKIT_IS_CLI === 'true';
  */
 export const COMMANDKIT_IS_TEST = process.env.COMMANDKIT_IS_TEST === 'true';
 
+/**
+ * Indicates that CommandKit is running in a build-like environment.
+ * @private
+ * @internal
+ */
+export function isBuildLikeEnvironment() {
+  const isCLI = process.env.COMMANDKIT_INTERNAL_IS_CLI_PROCESS === 'true';
+  if (isCLI) return true;
+
+  return process.env.COMMANDKIT_IS_BUILD === 'true';
+}
+
 /**
  * The current bootstrap mode of CommandKit.
  * This can be 'development' or 'production'.
diff --git a/packages/commandkit/src/utils/utilities.ts b/packages/commandkit/src/utils/utilities.ts
index 7f930eec..c5a7b7bc 100644
--- a/packages/commandkit/src/utils/utilities.ts
+++ b/packages/commandkit/src/utils/utilities.ts
@@ -4,6 +4,7 @@ import {
   COMMANDKIT_CWD,
   COMMANDKIT_IS_CLI,
   COMMANDKIT_IS_DEV,
+  isBuildLikeEnvironment,
 } from './constants';
 import { getConfig } from '../config/config';
 
@@ -169,6 +170,50 @@ export function devOnly any>(fn: T): T {
   return f as T;
 }
 
+/**
+ * Creates a function from the given function that runs only in build mode.
+ * @param fn The function to run in build mode.
+ * @returns The function that runs only in build mode.
+ * @example
+ * ```ts
+ * const buildOnlyFn = buildOnly(() => {
+ *   console.log('This function runs only in build mode');
+ * });
+ * buildOnlyFn(); // This will log the message only in build mode
+ * ```
+ */
+export function buildOnly any>(fn: T): T {
+  const f = (...args: Parameters) => {
+    if (isBuildLikeEnvironment()) {
+      return fn(...args);
+    }
+  };
+
+  return f as T;
+}
+
+/**
+ * Creates a function from the given function that runs only outside of build mode.
+ * @param fn The function to run outside of build mode.
+ * @returns The function that runs only outside of build mode.
+ * @example
+ * ```ts
+ * const noBuildOnlyFn = noBuildOnly(() => {
+ *   console.log('This function runs only outside of build mode');
+ * });
+ * noBuildOnlyFn(); // This will log the message only outside of build mode
+ * ```
+ */
+export function noBuildOnly any>(fn: T): T {
+  const f = (...args: Parameters) => {
+    if (!isBuildLikeEnvironment()) {
+      return fn(...args);
+    }
+  };
+
+  return f as T;
+}
+
 /**
  * Represents a simple proxy object that mirrors a target object.
  */