T
TanStack•2mo ago
harsh-harlequin

Docker image size with TanStack Start , pnpm

Hey folks 👋 I’m using TanStack Start with pnpm and Docker, and I’m noticing that my production Docker image is quite large 710 MB. Has anyone else experienced this? Is that size expected for a typical TanStack Start app, or might I be doing something wrong?
9 Replies
harsh-harlequin
harsh-harlequinOP•2mo ago
My package.json dependencies
"dependencies": {
"@tanstack/react-query": "5.81.5",
"@tanstack/react-query-devtools": "5.81.5",
"@tanstack/react-router": "1.125.3",
"@tanstack/react-router-devtools": "1.125.3",
"@tanstack/react-start": "1.125.3",
"better-auth": "1.2.12",
"class-variance-authority": "0.7.1",
"clsx": "2.1.1",
"date-fns": "4.1.0",
"drizzle-orm": "0.44.2",
"lucide-react": "0.525.0",
"pg": "8.16.3",
"react": "19.1.0",
"react-dom": "19.1.0",
"superjson": "2.2.2",
"tailwind-merge": "3.3.1",
"zod": "3.25.74"
},
"dependencies": {
"@tanstack/react-query": "5.81.5",
"@tanstack/react-query-devtools": "5.81.5",
"@tanstack/react-router": "1.125.3",
"@tanstack/react-router-devtools": "1.125.3",
"@tanstack/react-start": "1.125.3",
"better-auth": "1.2.12",
"class-variance-authority": "0.7.1",
"clsx": "2.1.1",
"date-fns": "4.1.0",
"drizzle-orm": "0.44.2",
"lucide-react": "0.525.0",
"pg": "8.16.3",
"react": "19.1.0",
"react-dom": "19.1.0",
"superjson": "2.2.2",
"tailwind-merge": "3.3.1",
"zod": "3.25.74"
},
In my Docker build I install only (production) dependencies using:
RUN pnpm install --frozen-lockfile --prod --ignore-scripts I did some digging on the image size, seems a lot comes from transitive deps via @tanstack/react-start, like @netlify/zip-it-and-ship-it, precinct, detective-typescript, typescript, prettier, etc.
Not sure if all of these need to be pulled in as dependencies of Start 🤔
correct-apricot
correct-apricot•2mo ago
What are you putting in your docker container? Build makes everything, including a apckage.json and a node_modules folder in the output folder
No description
harsh-harlequin
harsh-harlequinOP•2mo ago
@Roderik | SettleMint Ah, that makes sense, thanks! Switched to just copying the .output folder into the final image and dropped the extra installs. Now with node:24.3.0-alpine the image is down to 159 MB. Appreciate the tip! 🙌
correct-apricot
correct-apricot•2mo ago
use target: "bun", in the vite config and use the bun slim image for even less size and more speed
harsh-harlequin
harsh-harlequinOP•2mo ago
That’s crazy, tried it image size is around 100MB 🤯
Not sure if I’ll switch yet, how are you finding it in production? Any caveats or cons to be aware of?
generous-apricot
generous-apricot•2mo ago
Can you share the Dockerfile?
harsh-harlequin
harsh-harlequinOP•2mo ago
sorry don't have it anymore, just gave it a test run with bun, but for now sticking with node
correct-apricot
correct-apricot•2mo ago
FROM oven/bun:1.2.18-slim
WORKDIR /usr/src/app

COPY .output/ /usr/src/app

EXPOSE 3000/tcp
ENV NODE_ENV=production
USER bun
ENTRYPOINT [ "bun", "run", "server/index.mjs" ]
FROM oven/bun:1.2.18-slim
WORKDIR /usr/src/app

COPY .output/ /usr/src/app

EXPOSE 3000/tcp
ENV NODE_ENV=production
USER bun
ENTRYPOINT [ "bun", "run", "server/index.mjs" ]
but i compile on the CI

Did you find this page helpful?