Every backend eventually grows something that is not a request handler - a queue consumer, a mail sender, a cron runner, a listener speaking a protocol that is not HTTP.
A sidecar is a source folder for exactly that: it declares an entry point to build, and nothing else. No base, no routes, no pages/ or api/ tree.
src/
├── front/ React + Hono, base "/"
├── mailer/ sidecar - no pages/ no api/
│ └── entry.ts
└── smtp/ another one - one process per folder
└── entry.tsIt is still a source folder, so everything that follows from that still holds: ~/ points at it, @/ reaches shared code, its tsconfig.json covers it, and pnpm build builds it on its own.
Adding a Sidecar Folder
There is a sidecar command that seeds necessary files and wires everything together:
pnpm sidecar mailerWhat you get:
src/mailer/
├── kosmo.config.ts -> the sidecar block
├── tsconfig.json -> extends ../../lib/mailer/tsconfig.json
├── entry.ts -> defineService({ start, teardown })
└── run.ts -> imports the entry, starts it, stops it on a signalKeep it in its own folder
Nothing stops you defining sidecar next to frontend/backend in the same folder. It works. But you cannot serve, typecheck, build or deploy them separately:
pnpm build frontrebuilds the web app to ship a one-line worker change, and a broken worker fails the build that your site was waiting ontypecheckis a folder-level switch, so you cannot exempt a third-party worker entry without exempting your routes with it- the web app and the worker scale and restart on different schedules, yet ship as one artifact
A separate folder costs a kosmo.config.ts and gives you back pnpm build mailer, pnpm typecheck mailer, and a dist/mailer/ you can deploy on its own.