Practical Patterns
Generate routes with a bundler plugin
Run route generation before compilation and keep configuration in one source of truth.
Vite example
import { cookbookRouterVitePlugin } from '@cookbook/router-vite-plugin';
import { defineConfig } from 'vite';
export default defineConfig({
plugins: [cookbookRouterVitePlugin()],
});import { defineRouterConfig } from '@cookbook/router-cli';
export default defineRouterConfig({
routeFiles: 'src/**/*.route.{ts,tsx}',
outDir: '.cookbook-router',
});Keep route discovery in the router config unless the bundler instance genuinely needs an override. Explicit plugin routeFiles and outDir replace config values; they are not merged.
Consume physical artifacts
import { routes } from '../.cookbook-router/routes';routes.ts exists only for composable static exports. Always-generated successful outputs are contracts.ts, register.d.ts, and manifest.json.
Where this bites
Do not combine the plugin with an unrelated second generator writing the same directory. One owner per output avoids races, stale overwrites, and watch loops.