Before pyrpc can inject a bundler alias, it has to know which bundler you use. It never reads your package.json devDependencies, never executes your config, and never asks. It looks for files.
The signature map
_FRAMEWORK_SIGNATURES = {
"vite.config.ts": "vite",
"vite.config.js": "vite",
"vite.config.mjs": "vite",
"next.config.ts": "next",
"next.config.js": "next",
"next.config.mjs": "next",
}Six filenames, two frameworks, three extensions each. The detection is deliberately crude: a config file on disk is treated as proof the framework is in use. SvelteKit is covered because SvelteKit is Vite under the hood, a SvelteKit project has a vite.config.*, so the Vite path handles it with no extra entry.
The walk
_detect_bundler iterates the map in insertion order and returns the first existing file. Ordering encodes a deliberate preference: TypeScript configs (.ts) beat JavaScript ones, and vite.config.ts would be found before vite.config.js. If you keep both files around, the TypeScript one wins.
If no signature matches, None is returned and configure_bundler reports success without touching anything, an unknown bundler is not an error, it is an unknown that the throwing placeholder will safely police.
Why filename detection is the right tool
- Zero execution. Reading
package.jsonwould tell you the framework is installed, not that it is configured. The config file is the source of truth for the bundler. - Zero import cost. No config file is loaded, so config files that are not even JavaScript (e.g.
next.config.mjsthat imports stuff) are safe to detect. - Stateless and predictable. The same client directory always yields the same answer; a test can assert it without mocking a bundler.
What it cannot see
Filename detection has blind spots: a custom config name, a bundler configured inside a monorepo root config, or a future framework that uses a different file. When that happens the code takes the "no known config" path and leaves your setup alone, with the placeholder standing by as the loud failure mode. Detection is best-effort by design, correctness comes from the alias contract, not from perfect tooling coverage.
The takeaway
Heuristics work best when their failure is safe. Detecting a bundler by filename is fast, deterministic, and wrong only in ways that degrade gracefully. That is the pattern: use the cheapest reliable signal, and make the fallback loud rather than magical.

pyRPC