Project Detection
The @xtarterize/core package provides the detectProject() function — the foundation of xtarterize’s context-aware behavior. It analyzes your project directory to build a ProjectProfile that drives which conformance tasks are applicable.
detectProject() now acts as an orchestration layer in packages/core/src/detect.ts, while concrete detection adapters live in packages/core/src/detect/ (framework, bundler, router, styling, package manager, and monorepo).
Overview
Section titled “Overview”Project detection is the first step in every xtarterize command. It analyzes your project directory to build a ProjectProfile that drives which conformance tasks are applicable.
detectProject Function
Section titled “detectProject Function”import { detectProject } from '@xtarterize/core'
const profile = await detectProject('/path/to/project')ProjectProfile Schema
Section titled “ProjectProfile Schema”The detection returns a ProjectProfile object:
interface ProjectProfile { // Framework framework: 'react' | 'react-native' | 'vue' | 'svelte' | 'solid' | 'node' | null frameworkVersion: string | null
// Bundler bundler: 'vite' | 'nextjs' | 'tanstack-start' | 'expo' | 'webpack' | 'rspack' | 'none' | null
// Router router: 'tanstack-router' | 'react-router' | 'next' | 'expo-router' | 'vue-router' | null
// Styling styling: ('tailwind' | 'css-modules' | 'styled-components' | 'vanilla-extract' | 'nativewind' | 'vanilla')[]
// Language & Runtime typescript: boolean runtime: 'browser' | 'node' | 'edge' | 'native' | 'universal'
// Package manager packageManager: 'npm' | 'pnpm' | 'yarn' | 'bun'
// Repo structure monorepo: boolean monorepoTool: 'turbo' | 'nx' | 'lerna' | null workspaceRoot: boolean
// Git hasGitHub: boolean hasGit: boolean
// Existing config presence existing: { biome: boolean tsconfig: boolean renovate: boolean commitlint: boolean knip: boolean plop: boolean turbo: boolean vscodeSettings: boolean agentsMd: boolean githubWorkflows: string[] viteConfig: boolean versionrc: boolean gitignore: boolean }}Detection Logic
Section titled “Detection Logic”Detection modules
Section titled “Detection modules”framework.ts— framework/runtime/vite-plus detectionbundler.ts— bundler detection from deps and config filesrouter.ts— router detection from bundler + depsstyling.ts— styling solution detectionpackage-manager.ts— lockfile/nypm package manager detectionmonorepo.ts— workspace/monorepo detectiontypes.ts+utils.ts— shared detection types and guards
flowchart TD
A[package.json] --> B{Dependencies}
B --> C[detectFramework]
B --> D[detectBundler]
B --> E[detectRouter]
B --> F[detectStyling]
B --> G[detectVitePlus]
C --> H{Framework?}
H -->|"react-native + react"| I["Ambiguous → prompt user"]
H -->|react| J["Framework: react"]
H -->|vue| K["Framework: vue"]
H -->|svelte| L["Framework: svelte"]
H -->|solid| M["Framework: solid"]
H -->|node| N["Framework: node"]
D --> O{Bundler?}
O -->|"@tanstack/start"| P["TanStack Start"]
O -->|next| Q["Next.js"]
O -->|expo| R["Expo"]
O -->|vite| S["Vite"]
O -->|webpack| T["Webpack"]
O -->|"@rspack/core"| U["Rspack"]
O -->|none| V["None"]
E --> W{Router?}
W -->|"nextjs bundler"| X["Next Router"]
W -->|"expo bundler"| Y["Expo Router"]
W -->|"@tanstack/react-router"| Z["TanStack Router"]
W -->|react-router| AA["React Router"]
W -->|vue-router| AB["Vue Router"]
style A fill:#6366f1,color:#fff
style C fill:#22c55e,color:#fff
style D fill:#22c55e,color:#fff
Detection Sources
Section titled “Detection Sources”| Signal | Source |
|---|---|
| Framework | package.json dependencies (react, vue, react-native, etc.) |
| Bundler | vite, next, expo, webpack, @rspack/core in deps |
| Router | @tanstack/react-router, react-router-dom, vue-router in deps |
| Styling | tailwindcss, styled-components, nativewind in deps |
| Signal | Source |
|---|---|
| TypeScript | tsconfig.json existence, typescript in deps |
| Package manager | Lockfile presence (pnpm-lock.yaml, yarn.lock, etc.) |
| Monorepo | pnpm-workspace.yaml, turbo.json, packages/ + apps/ dirs |
| GitHub | .github/ directory presence |
Ambiguity Handling
Section titled “Ambiguity Handling”Example
Section titled “Example”const profile = await detectProject('/path/to/project')
if (profile.bundler === 'vite' && profile.typescript) { // Vite plugin tasks will be applicable}
if (profile.monorepo && profile.monorepoTool === 'turbo') { // Turbo task may be skip if already configured}References
Section titled “References”- npm package.json Documentation — Package manifest format
- React — UI library for web and native apps
- Vue.js — Progressive JavaScript framework
- React Native — Native app development with React
- Vite — Next-generation frontend build tool
- Next.js — React framework for production
- TanStack Router — Type-safe routing for React
- React Router — Declarative routing for React
- Vue Router — Official router for Vue.js
- Expo — React Native framework
- Webpack — Module bundler
- Rspack — Fast Rust-based web bundler
- Tailwind CSS — Utility-first CSS framework
- Styled Components — CSS-in-JS for React
- NativeWind — Tailwind CSS for React Native
- pnpm Workspaces — Monorepo workspace support
- Turborepo — Monorepo task runner
- TypeScript tsconfig — Compiler configuration