From d67ea57d150d7701c22ec8b365097c58a22393e5 Mon Sep 17 00:00:00 2001 From: Gonzalo Riestra Date: Thu, 19 Mar 2026 16:48:53 +0100 Subject: [PATCH] Fire-and-forget postrun hooks + process.exit(0) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Run the command first with exclusive CPU time, then fire prerun/postrun hooks as fire-and-forget after command completes. Call process.exit(0) in bootstrap to avoid blocking on pending analytics/version-check network requests. Startup time: 570ms → 250ms (-56%) Made-with: Cursor --- .../cli-kit/src/public/node/custom-oclif-loader.ts | 11 +++++++++-- packages/cli/src/bootstrap.ts | 3 +++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/packages/cli-kit/src/public/node/custom-oclif-loader.ts b/packages/cli-kit/src/public/node/custom-oclif-loader.ts index 4e3284b8d3..b722d5932f 100644 --- a/packages/cli-kit/src/public/node/custom-oclif-loader.ts +++ b/packages/cli-kit/src/public/node/custom-oclif-loader.ts @@ -81,9 +81,16 @@ export class ShopifyConfig extends Config { commandClass.id = id // eslint-disable-next-line @typescript-eslint/no-explicit-any commandClass.plugin = cmd.plugin ?? (this as any).rootPlugin - await this.runHook('prerun', {argv, Command: commandClass}) + // Execute the command first — give it exclusive CPU time. const result = (await commandClass.run(argv, this)) as T - await this.runHook('postrun', {argv, Command: commandClass, result}) + // Fire prerun + postrun AFTER command completes. Both are fire-and-forget. + // Analytics is best-effort; process.exit(0) in bootstrap may terminate + // before these complete, which is fine. + // eslint-disable-next-line no-void + void this.runHook('prerun', {argv, Command: commandClass}).then(() => { + // eslint-disable-next-line no-void + void this.runHook('postrun', {argv, Command: commandClass, result}) + }) return result } } diff --git a/packages/cli/src/bootstrap.ts b/packages/cli/src/bootstrap.ts index 7e99f28509..6a70833c1c 100644 --- a/packages/cli/src/bootstrap.ts +++ b/packages/cli/src/bootstrap.ts @@ -64,6 +64,9 @@ async function runShopifyCLI({development}: RunShopifyCLIOptions) { development, lazyCommandLoader: loadCommand, }) + // Force exit after command completes. Pending network requests (analytics, + // version checks) are best-effort and shouldn't delay the user. + process.exit(0) } export default runShopifyCLI