pub fn detect_from_config(project_root: &Path) -> Option<StackLabel>Expand description
Detect a stack label from configuration files in a project root.
The function scans only project_root and checks built-in rules in a fixed
priority order. More specific frontend framework config files are evaluated
before generic runtime markers such as Cargo.toml or go.mod. Node
projects are also recognized from package.json dependencies: next
(Next.js without a config file), @nestjs/core (NestJS, also from
nest-cli.json), Remix packages such as @remix-run/react (Remix, even
with vite.config.ts), and express under "dependencies" (Express,
only when no other rule matches, so a repo with package.json and
Cargo.toml, go.mod, or a .csproj keeps the label of that build).
react-router.config.ts is React Router, and svelte.config.js is
SvelteKit only when package.json lists @sveltejs/kit (plain Svelte
with Vite is Vite). Python
projects get a second pass that can identify Django, Flask, FastAPI,
Starlette, and Litestar from entry files or dependency files. Ruby
projects need Gemfile and config.ru (Ruby (Rack)), plus bin/rails
for Rails. PHP projects with artisan next to composer.json are
Laravel, and those with symfony.lock or bin/console are Symfony.
Maven and Gradle builds that use org.springframework.boot are
Spring Boot, and a mix.exs that depends on :phoenix is Phoenix; a
multi-module Gradle root with only settings.gradle or
settings.gradle.kts is a Gradle project.
This function knows nothing about the process, so it uses the same rules
StackDetector applies to an unknown process.
Python entry files such as server.py alone do not make a Python project
when package.json is present without a Python dependency file. The
detector narrows the rules to the process’s ecosystem: a php process in a
Laravel project with vite.config.js is Laravel, while a node process
there is Vite.
§Examples
use std::path::Path;
use what_stack::detect_from_config;
let label = detect_from_config(Path::new("/workspace/api"));
println!("{label:?}");§Performance
Directory entries are read once into a small in-memory set. Source and
dependency files used for Python detection are capped to the first 64 KiB.
Python frameworks come from entry files and from dependency manifests
(pyproject.toml, requirements.txt, requirements-dev.txt, Pipfile,
setup.py), ignoring # comment lines. Lock files (uv.lock,
poetry.lock) list transitive dependencies, so they only confirm a
framework a manifest names and never add one.