Skip to content

Commit 40f806b

Browse files
Inline app-init and hydrogen-init hooks
Replace re-exports from @shopify/app and @shopify/cli-hydrogen with inlined versions. app-init now lazily imports LocalStorage instead of pulling the entire @shopify/app chain (~1s). hydrogen-init skips loading @shopify/cli-hydrogen entirely for non-hydrogen commands (~300ms). Startup time: 710ms → 530ms (-25%) Made-with: Cursor
1 parent 4bad0ca commit 40f806b

File tree

2 files changed

+37
-5
lines changed

2 files changed

+37
-5
lines changed

packages/cli/src/hooks/app-init.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,20 @@
1-
export {AppInitHook as default} from '@shopify/app'
1+
import {Hook} from '@oclif/core'
2+
import {randomUUID} from 'crypto'
3+
4+
/**
5+
* Inlined version of the `\@shopify/app` init hook.
6+
* The original hook imports `\@shopify/app` → local-storage → cli-kit error chain (~1s).
7+
* This inlined version avoids those imports entirely. It lazily imports the
8+
* LocalStorage class only at call time, and uses Node's native crypto.
9+
*/
10+
const init: Hook<'init'> = async (_options) => {
11+
// Lazy import to clear the command storage (equivalent to clearCachedCommandInfo)
12+
const {LocalStorage} = await import('@shopify/cli-kit/node/local-storage')
13+
const store = new LocalStorage({projectName: 'shopify-cli-app-command'})
14+
store.clear()
15+
16+
// Set a unique run ID so parallel commands don't collide in the cache
17+
process.env.COMMAND_RUN_ID = randomUUID()
18+
}
19+
20+
export default init
Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,19 @@
1-
import {HOOKS} from '@shopify/cli-hydrogen'
2-
import type {Hook} from '@oclif/core'
1+
import {Hook} from '@oclif/core'
2+
3+
/**
4+
* Hydrogen init hook — only loads `@shopify/cli-hydrogen` when running a hydrogen command.
5+
* This avoids the ~300ms+ import cost for non-hydrogen commands.
6+
*/
7+
const hook: Hook<'init'> = async (options) => {
8+
if (!options.id?.startsWith('hydrogen:') || options.id === 'hydrogen:init') {
9+
return
10+
}
11+
12+
const {HOOKS} = await import('@shopify/cli-hydrogen')
13+
if (HOOKS.init && typeof HOOKS.init === 'function') {
14+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
15+
await (HOOKS.init as any).call(this, options)
16+
}
17+
}
318

4-
// cast through unknown because cli-hydrogen uses @oclif/core v3 while this package uses v4
5-
const hook = HOOKS.init as unknown as Hook<'init'>
619
export default hook

0 commit comments

Comments
 (0)