Migration from 0.26 to 0.27
What's new in 0.27?
New npm organization
Wasp's npm packages moved from the @wasp.sh organization to @wasp. The Wasp CLI is now published as @wasp/cli, and the Wasp Spec is @wasp/spec.
Prisma 6
Wasp now uses Prisma 6. Check out Prisma's upgrade guide for the full list of changes.
Testing with your own Vitest setup
Wasp no longer installs and runs Vitest for you. You set it up like in any other Vite app, so you choose the versions of Vitest and the testing libraries.
The wasp/client/test helpers for rendering components and mocking queries and APIs still work. Read more in the testing docs.
Smaller Docker images
The server's Docker image now contains only the files the server needs at runtime, instead of the whole node_modules folder. This makes the image about half the size.
Wasp finds those files by analyzing the server's imports. Some packages load their files in a non-standard way that this analysis can't follow, and you might need to list them in server.traceDeps.
The build steps are also ordered so that a code change reuses the installed dependencies, which makes rebuilding the image after a code change faster.
How to migrate?
1. Switch to the new Wasp CLI package
The Wasp CLI is now published as @wasp/cli instead of @wasp.sh/wasp-cli. Uninstall the old package first, otherwise npm fails with an EEXIST error when installing the new one:
npm uninstall -g @wasp.sh/wasp-cli
npm i -g @wasp/cli@0.27
2. Rename @wasp.sh/spec to @wasp/spec
Wasp's packages moved from the @wasp.sh npm scope to @wasp. Rename the Wasp Spec dependency in your package.json:
- Before
- After
{
"devDependencies": {
"@wasp.sh/spec": "file:.wasp/spec"
}
}
{
"devDependencies": {
"@wasp/spec": "file:.wasp/spec"
}
}
Then replace @wasp.sh/spec with @wasp/spec everywhere else in your project. That covers the imports in main.wasp.ts and any other *.wasp.ts files, and mentions in files like AGENTS.md or CLAUDE.md:
- Before
- After
import { app, page, route } from "@wasp.sh/spec";
import { app, page, route } from "@wasp/spec";
3. Bump the Wasp version
Update the version field in your Wasp config to ^0.27.0.
- Before
- After
export default app({
wasp: { version: "^0.26.0" },
// ...
});
export default app({
wasp: { version: "^0.27.0" },
// ...
});
And run the following command to update the Wasp libraries in your project:
wasp install
4. Update your Vitest setup
The wasp test command is gone, and Wasp no longer installs testing libraries or configures Vitest for you. The wasp/client/test helpers (renderInContext and mockServer) stay, but they now need vitest, msw, and @testing-library/react in your project's devDependencies.
Follow the part that matches your app.
If you don't use wasp test client
Wasp no longer needs vitest, so you can remove it from your project:
-
If your
vite.config.tsimportsdefineConfigfromvitest/config, import it fromviteinstead, and remove thetestsection. Otherwise, Vite can't load your config after you removevitest.- Before
- After
vite.config.tsimport { defineConfig } from "vitest/config";import { wasp } from "wasp/client/vite";export default defineConfig({plugins: [wasp()],test: {exclude: ["./e2e-tests/**"],},});vite.config.tsimport { defineConfig } from "vite";import { wasp } from "wasp/client/vite";export default defineConfig({plugins: [wasp()],}); -
Remove
vitestfrom yourdevDependencies:- Before
- After
package.json{"devDependencies": {"vitest": "^4.1.9","vite": "^8.1.0"}}package.json{"devDependencies": {"vite": "^8.1.0"}} -
Remove the
vitest/globalsand@testing-library/jest-domreferences fromsrc/vite-env.d.ts, if you have them:- Before
- After
src/vite-env.d.ts/// <reference types="vite/client" />/// <reference types="vitest/globals" />/// <reference types="@testing-library/jest-dom" />src/vite-env.d.ts/// <reference types="vite/client" />
If you use wasp test client
-
Install Vitest and the testing libraries your tests use:
npm install -D vitest jsdom @testing-library/react @testing-library/jest-dom mswWasp's testing helpers need Vitest 5 and MSW 3, so this also upgrades Vitest if your project is on an older version. If your tests use Vitest features that changed, check Vitest's migration guide.
-
Set up Vitest in your
vite.config.tswith Wasp'swaspTestConfighelper. It sets the options Wasp used to set for you:- Before
- After
vite.config.tsimport { defineConfig } from "vite";import { wasp } from "wasp/client/vite";export default defineConfig({plugins: [wasp()],});vite.config.tsimport { defineConfig } from "vitest/config";import { wasp } from "wasp/client/vite";import { waspTestConfig } from "wasp/test";export default defineConfig({plugins: [wasp()],test: waspTestConfig({setupFiles: ["./src/test/setup.ts"],}),});Wasp used to make
test,expect, and the other test functions available globally. If your tests use them without importing them, passglobals: truetowaspTestConfig:- Before
- After
vite.config.tstest: waspTestConfig({setupFiles: ["./src/test/setup.ts"],}),vite.config.tstest: waspTestConfig({setupFiles: ["./src/test/setup.ts"],globals: true,}),Keep the
vitest/globalstypes insrc/vite-env.d.ts, so TypeScript knows about the globals when Wasp type-checks your tests:src/vite-env.d.ts/// <reference types="vite/client" />/// <reference types="vitest/globals" />Or import them from
vitestin each test file instead:- Before
- After
src/utils.test.tsimport { add } from "./utils";test("adds numbers", () => {expect(add(1, 2)).toBe(3);});src/utils.test.tsimport { expect, test } from "vitest";import { add } from "./utils";test("adds numbers", () => {expect(add(1, 2)).toBe(3);}); -
Create the setup file you referenced in
setupFiles. It adds the DOM matchers, liketoBeInTheDocument(), and removes what a test rendered when the test ends:src/test/setup.tsimport "@testing-library/jest-dom/vitest";import { cleanup } from "@testing-library/react";import { afterEach } from "vitest";afterEach(() => {cleanup();});The
import "@testing-library/jest-dom/vitest"line also adds the types for the DOM matchers, so you can remove the@testing-library/jest-domreference fromsrc/vite-env.d.ts:- Before
- After
src/vite-env.d.ts/// <reference types="vite/client" />/// <reference types="vitest/globals" />/// <reference types="@testing-library/jest-dom" />src/vite-env.d.ts/// <reference types="vite/client" />/// <reference types="vitest/globals" /> -
Run your tests with Vitest instead of
wasp test client. Add atestscript to yourpackage.json, or change it if it runswasp test client:- Before
- After
package.json{"scripts": {"test": "wasp test client"}}package.json{"scripts": {"test": "vitest"}}Your tests import the Wasp SDK, so generate it first with
wasp compile, or keepwasp startrunning in another terminal:wasp compilenpm test
Read more in the testing docs.
5. Upgrade to Prisma 6
Update the Prisma packages in your package.json:
- Before
- After
{
"dependencies": {
"@prisma/client": "5.19.1" // if already present
},
"devDependencies": {
"prisma": "5.19.1"
}
}
{
"dependencies": {
"@prisma/client": "6.19.3" // if already present
},
"devDependencies": {
"prisma": "6.19.3"
}
}
Then run:
wasp install
wasp db migrate-dev
Prisma 6 changed how some things are stored in the database, so wasp db migrate-dev creates a new migration if your app needs one. Prisma 6 also has a few breaking changes in Prisma Client. Check Prisma's upgrade guide to see if any of them affect your app.
6. Check relative paths in your server code
The server now runs with your project's root directory as its working directory, instead of .wasp/out/server. In the Docker image, that's /app instead of /app/.wasp/out/server.
If your server code reads or writes files using relative paths, they now resolve from the project root. If you worked around the old behavior (e.g. with paths like ../../../src/data/countries.json), remove the workaround. If you deploy with Docker and mount a volume at a path inside /app/.wasp/out/server, move it to the matching path inside /app.
7. Check the packages your server loads at runtime
If you didn't add any npm packages to your app yourself, you can skip this step. The packages Wasp uses work out of the box.
Otherwise, check if any of the packages your server uses serve or load files from their own folder, like swagger-ui-express.
The Docker image now contains only the files Wasp finds by following the server's imports. A package that loads files in a non-standard way misses them in the image. A common case is a package that serves static assets from its own folder (e.g. swagger-ui-express), which would fail in production.
List such packages in server.traceDeps to copy all of their files:
export default app({
// ...
server: {
traceDeps: ["swagger-ui-dist*"],
},
})
8. Install the system dependencies your app needs
If your app doesn't run Python on the server, you can skip this step.
The generated Dockerfile no longer installs python3 in the final image, because the Wasp server doesn't use it. If your app runs Python, install it in a custom Dockerfile:
RUN apk add --no-cache python3
9. Update your custom Dockerfile
If you don't have a Dockerfile in your project's dir, you can skip this step.
The generated Dockerfile changed. Run wasp dockerfile to print it with your custom Dockerfile appended at the bottom, and check that your steps still apply to the new stages.
The final stage (server-production) no longer contains the /app/node_modules folder. It only has the server's bundle and the packages the bundle uses, in /app/.wasp/out/server. If your steps use other packages (for example, through npx), copy the full node_modules from the server-builder stage:
COPY --from=server-builder /app/node_modules /app/node_modules
10. Enjoy your updated Wasp app
That's it!