Skip to content
ChatfuelSDK
Reference

Scripts in the generated app

Every npm script the scaffolded app ships with — what it runs, when you reach for it, and what has to be true first.

Every command below is npm run <name> from the app root, except npm start and npm test, which npm lets you type without the run.

The scripts

ScriptWhat it runsWhen you reach for itWhat has to be true first
devviteDay to day. Serves the app on port 5173 with the Chatfuel proxy plugin registered, so the token stays server-side.Dependencies installed, and a .env with CHATFUEL_TOKEN.
buildvite build && vite build -c vite.server.config.tsBefore start, and in a Docker image. Builds both halves.The VITE_* values you build with must match the ones the server will run with.
build:clientvite buildThe browser bundle alone. This is also what Vercel runs.Same.
build:servervite build -c vite.server.config.tsThe server bundle alone, into server/dist/entry.js. Targets node22, and leaves ws, undici and https-proxy-agent external. Plugin-free on purpose — it never touches the client.—
codegennode scripts/codegen.mjsAfter you edit a GraphQL document under src/vendor/api/operations/.The generator toolchain. The first run prints the one command that installs it and stops.
startnode server/dist/entry.jsRunning the built app on your own host. Serves dist/ and proxies Chatfuel traffic, HTTP and WebSocket, with the token injected server-side.build or build:server has run. Listens on PORT, default 3000, and on HOST when you set one.
deploynode scripts/deploy-vercel.mjsPutting the app on Vercel, with no Git repository and no dashboard.A .env that passes its checks.
connect-gitnode scripts/connect-git.mjsMaking git push deploy, once there is a repository.A linked Vercel project — .vercel/project.json, written by deploy — and an origin remote.
checktsc --noEmit && tsc -p tsconfig.scripts.jsonBefore a commit. Two passes, because the app's tsconfig.json covers src, server, api and the two Vite configs and nothing else; the second pass is scripts/, which is JavaScript and is only type-checked because that config turns checkJs on.—
testvitest runBefore a commit, and after any change to a module's root component.—

start also reads a .env sitting next to the app, so npm run build && npm start behaves like npm run dev on a dev machine. Real environment variables win over the file, which is why the load is safe to keep in a deployed image.

Vercel builds with build:client only. server/entry.ts is never built or run there — the Vercel deployment answers Chatfuel traffic from api/chatfuel.ts instead, through the rewrite in vercel.json, with a maxDuration of 300 seconds. A change you make to the Node server shows up under npm start and in Docker, and nowhere on Vercel.

What codegen actually does

The generator is not a dependency of this app: it is 265 packages and 62 MB that nothing but this command needs. So npm run codegen installs nothing. When the toolchain is absent it prints the one command that adds it — with the versions already filled in, and using whichever package manager wrote the lockfile it finds — and exits.

The versions are pinned rather than ranged because the plugins decide the shape of the generated code. A patch release that renames a generated type is not a break for graphql-codegen; it is a break for every file in the app that imports one.

npm install --save-dev --save-exact \
  @graphql-codegen/cli@5.0.7 \
  @graphql-codegen/typescript@4.1.6 \
  @graphql-codegen/typescript-operations@4.6.1 \
  @graphql-codegen/typed-document-node@5.1.2 \
  @graphql-codegen/visitor-plugin-common@5.8.0 \
  tsx@4.23.12

Copy the line the run prints rather than this one — it is filled in for whichever package manager wrote your lockfile.

With the toolchain installed it runs graphql-codegen --config codegen.ts, then the fragment-hoisting pass, then writes src/vendor/api/generated/.codegen-inputs.json — sha256 digests of the schema and of each operations file, in the same encoding .chatfuel/lock.json uses. update refreshes the schema and the documents but cannot regenerate the client, so it compares those digests against the files on disk and tells you when the two have parted. The whole cycle is on the operations page.

What deploy actually does

Re-running is the normal case, so every step is idempotent: an existing .vercel/project.json is kept and the project is never re-created.

What test covers

Every module ships a render test that mounts its root component and renders the tree to a string. It runs without a browser, which is the point: nothing else in the app can catch a component that type-checks, passes every other gate and renders nothing.

The suite is the app's own. The design system and the API client are vendored as sources, but their tests are stripped on the way in — a scaffolded app should not hand you failing runs for code you did not write. Modules you did not select are deleted from the tree, so their tests go with them.

On this page