> Part of the walkerOS documentation. Project overview and full index: <https://www.walkeros.io/llms.txt>

# Migrating to @walkeros/cli 4.x

The bundler now uses [`@vercel/nft`](https://github.com/vercel/nft) to trace server flow dependencies and ship only the files actually used. flow\.json field locations are unchanged. The migration is a small, mechanical edit to your Dockerfile and (if you used it) the `walkerOS.bundle.external` annotation.

## flow\.json schema is unchanged[​](#flowjson-schema-is-unchanged "Direct link to flow.json schema is unchanged")

`version: 4` stays. `flow.<name>.config.bundle.packages`, `flow.<name>.config.bundle.overrides`, and `flow.<name>.config.bundle.traceInclude` remain the canonical locations for build-time fields.

## Remove `flow.<name>.config.bundle.external` entirely[​](#remove-flownameconfigbundleexternal-entirely "Direct link to remove-flownameconfigbundleexternal-entirely")

nft handles externalization automatically. Remove the field; it is no longer recognized.

```
 "config": {

   "platform": "server",

   "bundle": {

     "packages": {...},

-    "external": ["@google-cloud/bigquery-storage", "@grpc/grpc-js"]

   }

 }
```

The CLI prints a deprecation warning if it sees a v3-era `config.bundle.external` block. The same applies to step-package manifests carrying `walkerOS.bundle.external` (also no longer recognized).

## Update the Dockerfile[​](#update-the-dockerfile "Direct link to Update the Dockerfile")

Server bundles are always a directory now: `dist/{flow.mjs, package.json, node_modules/}`. If your Dockerfile copied just `bundle.mjs`, change it to copy the whole directory and bump the runtime image:

```
 FROM node:22.23.0-alpine AS builder

 WORKDIR /build

 RUN npm init -y && npm install --save-dev @walkeros/cli

 COPY flow.json ./

-RUN npx walkeros bundle ./flow.json --output dist/bundle.mjs

+RUN npx walkeros bundle flow.json -o dist/



-FROM walkeros/flow:3.3.0

-COPY --from=builder /build/dist/bundle.mjs /app/flow/bundle.mjs

-ENV BUNDLE=/app/flow/bundle.mjs

-ENV FILES_PATH=/app/flow

+FROM walkeros/flow:4

+WORKDIR /app/flow

+COPY --from=builder /build/dist/ ./

 ENV PORT=8080

 EXPOSE 8080
```

The `BUNDLE` and `FILES_PATH` env vars are no longer needed: the runtime image's defaults match `/app/flow/flow.mjs`.

## You no longer need `npm install` for step packages[​](#you-no-longer-need-npm-install-for-step-packages "Direct link to you-no-longer-need-npm-install-for-step-packages")

Pacote drives the install layer based on `flow.<name>.config.bundle.packages`. Your project's `package.json` only needs `@walkeros/cli` as a devDependency (plus any local code your project ships, of course). You can remove pinned `@walkeros/...` deps from `package.json` if you previously listed them just to satisfy the bundler.

## Escape hatch: `traceInclude`[​](#escape-hatch-traceinclude "Direct link to escape-hatch-traceinclude")

If nft cannot statically reach a runtime asset (rare: `require(somePathFromEnv)`), declare it explicitly under the per-flow bundle block:

```
"flows": {

  "default": {

    "config": {

      "platform": "server",

      "bundle": {

        "packages": { "@walkeros/server-destination-gcp": {} },

        "traceInclude": [

          "node_modules/some-pkg/data/*.json"

        ]

      }

    }

  }

}
```

Paths and globs both work. They resolve against the install root (where pacote put files), not your project directory.

## Output filename change[​](#output-filename-change "Direct link to Output filename change")

Default output filename is now `flow.mjs` (was `bundle.mjs`). The runtime image expects `/app/flow/flow.mjs`. If you have scripts that read `dist/bundle.mjs`, update them.
