# How GitNexus Performs Framework Detection to Identify Project Types and Entry Points

> Learn how GitNexus uses hybrid framework detection, analyzing file paths and AST decorators to identify project types and boost entry point scores with specific multipliers.

- Repository: [Abhigyan Patwari/GitNexus](https://github.com/abhigyanpatwari/GitNexus)
- Tags: internals
- Published: 2026-03-08

---

**GitNexus uses a hybrid framework detection system that analyzes file path conventions and AST-level decorators to identify project types, then applies framework-specific multipliers (2.0–3.0×) to boost entry point scores.**

GitNexus is an open-source code analysis engine that automatically maps repository structure and identifies critical entry points. At the core of this capability lies its **framework detection** logic, implemented in [`gitnexus/src/core/ingestion/framework-detection.ts`](https://github.com/abhigyanpatwari/GitNexus/blob/main/gitnexus/src/core/ingestion/framework-detection.ts). The system combines static path analysis with lightweight AST parsing to recognize frameworks ranging from Next.js and Django to Laravel and NestJS.

## Path-Based Framework Detection

The primary detection mechanism inspects file paths using `detectFrameworkFromPath()`. This function normalizes paths to lowercase with forward slashes, then matches against known directory conventions and filename patterns.

```typescript
export function detectFrameworkFromPath(filePath: string): FrameworkHint | null {
  let p = filePath.toLowerCase().replace(/\\/g, '/');
  if (!p.startsWith('/')) p = '/' + p;

  // Next.js Pages Router
  if (p.includes('/pages/') && !p.includes('/_') && !p.includes('/api/')) {
    if (p.endsWith('.tsx') || p.endsWith('.ts') || p.endsWith('.jsx') || p.endsWith('.js')) {
      return { framework: 'nextjs-pages', entryPointMultiplier: 3.0, reason: 'nextjs-page' };
    }
  }

  // Next.js App Router
  if (p.includes('/app/') && (p.endsWith('page.tsx') || p.endsWith('page.ts') ||
                               p.endsWith('page.jsx') || p.endsWith('page.js'))) {
    return { framework: 'nextjs-app', entryPointMultiplier: 3.0, reason: 'nextjs-app-page' };
  }

  // Django views
  if (p.endsWith('views.py')) {
    return { framework: 'django', entryPointMultiplier: 3.0, reason: 'django-views' };
  }

  // Laravel routes
  if (p.includes('/routes/') && p.endsWith('.php')) {
    return { framework: 'laravel', entryPointMultiplier: 3.0, reason: 'laravel-routes' };
  }

  return null;
}

```

Each match returns a **FrameworkHint** containing the framework identifier, an **entry point multiplier** (typically 2.5–3.0), and a detection reason. If no pattern matches, the function returns `null`, signaling the scoring algorithm to use a neutral multiplier of 1.0.

## AST-Based Framework Detection

For frameworks that rely on decorators or annotations, GitNexus employs `detectFrameworkFromAST()`. This function examines the first ~300 characters of a declaration's source text to identify framework-specific markers without requiring full AST parsing.

```typescript
export function detectFrameworkFromAST(
  language: string,
  definitionText: string
): FrameworkHint | null {
  if (!language || !definitionText) return null;

  const configs = AST_PATTERNS_LOWERED[language.toLowerCase()];
  if (!configs?.length) return null;

  const normalized = definitionText.toLowerCase();

  for (const cfg of configs) {
    for (const pattern of cfg.patterns) {
      if (normalized.includes(pattern)) {
        return {
          framework: cfg.framework,
          entryPointMultiplier: cfg.entryPointMultiplier,
          reason: cfg.reason,
        };
      }
    }
  }
  return null;
}

```

The detection relies on `AST_PATTERNS_LOWERED`, a pre-computed table mapping languages to framework patterns. For example, TypeScript entries include `@Controller` for NestJS, while Rust entries include `#[get]` for Actix. By lowercasing both the pattern table and source text, GitNexus achieves O(1) lookups with simple string inclusion checks.

## How Framework Detection Influences Entry Point Scoring

Framework detection directly impacts entry point identification through multipliers applied in `calculateEntryPointScore()`. Located in [`gitnexus/src/core/ingestion/entry-point-scoring.ts`](https://github.com/abhigyanpatwari/GitNexus/blob/main/gitnexus/src/core/ingestion/entry-point-scoring.ts), this function invokes `detectFrameworkFromPath()` and applies the returned multiplier to boost the final score.

```typescript
export function calculateEntryPointScore(
  name: string,
  language: string,
  isExported: boolean,
  callerCount: number,
  calleeCount: number,
  filePath: string = ''
): EntryPointScoreResult {
  // Base score calculation...
  
  let frameworkMultiplier = 1.0;
  if (filePath) {
    const frameworkHint = detectFrameworkFromPath(filePath);
    if (frameworkHint) {
      frameworkMultiplier = frameworkHint.entryPointMultiplier;
      reasons.push(`framework:${frameworkHint.reason}`);
    }
  }

  const finalScore = baseScore * exportMultiplier * nameMultiplier * frameworkMultiplier;
  return { score: finalScore, reasons };
}

```

When a file matches a framework pattern—such as a Next.js page or Laravel route—the **entry point multiplier** (typically 2.0–3.0×) significantly increases the candidate's score. This ensures framework-specific entry points surface above generic utility functions during repository analysis.

## Practical Usage Examples

Developers can leverage GitNexus's framework detection API directly for custom tooling:

```typescript
import { detectFrameworkFromPath, detectFrameworkFromAST } from './framework-detection';

// Detect Next.js App Router from file path
const pathHint = detectFrameworkFromPath('src/app/dashboard/page.tsx');
// Returns: { framework: 'nextjs-app', entryPointMultiplier: 3, reason: 'nextjs-app-page' }

// Detect NestJS from decorator usage
const codeSnippet = '@Controller("users")\nexport class UsersController {}';
const astHint = detectFrameworkFromAST('typescript', codeSnippet);
// Returns: { framework: 'nestjs', entryPointMultiplier: 3.2, reason: 'nestjs-decorator' }

```

These functions return `null` when no framework is detected, allowing fallback logic to proceed with neutral scoring.

## Key Implementation Files

| File | Purpose |
|------|---------|
| [`gitnexus/src/core/ingestion/framework-detection.ts`](https://github.com/abhigyanpatwari/GitNexus/blob/main/gitnexus/src/core/ingestion/framework-detection.ts) | Core detection logic implementing `detectFrameworkFromPath()` and `detectFrameworkFromAST()`; defines pattern tables and `FrameworkHint` interface. |
| [`gitnexus/src/core/ingestion/entry-point-scoring.ts`](https://github.com/abhigyanpatwari/GitNexus/blob/main/gitnexus/src/core/ingestion/entry-point-scoring.ts) | Consumes framework hints to apply multipliers during entry point calculation via `calculateEntryPointScore()`. |
| [`gitnexus/test/unit/framework-detection.test.ts`](https://github.com/abhigyanpatwari/GitNexus/blob/main/gitnexus/test/unit/framework-detection.test.ts) | Unit tests validating detection accuracy across supported languages and frameworks. |
| [`gitnexus/src/core/ingestion/workers/parse-worker.ts`](https://github.com/abhigyanpatwari/GitNexus/blob/main/gitnexus/src/core/ingestion/workers/parse-worker.ts) | Orchestration layer where AST-based detection is triggered during source parsing. |

## Summary

- **GitNexus employs dual detection strategies**: path-based pattern matching for directory conventions and AST-based scanning for decorators or annotations.
- **Path detection** in `detectFrameworkFromPath()` recognizes frameworks by analyzing file locations (e.g., [`/app/page.tsx`](https://github.com/abhigyanpatwari/GitNexus/blob/main//app/page.tsx) for Next.js, [`views.py`](https://github.com/abhigyanpatwari/GitNexus/blob/main/views.py) for Django).
- **AST detection** in `detectFrameworkFromAST()` identifies framework-specific markers like `@Controller` or `#[get]` by scanning the first 300 characters of declarations.
- **Framework hints** boost entry point scores by 2.0–3.0× in `calculateEntryPointScore()`, ensuring framework-specific files rank higher as project entry points.

## Frequently Asked Questions

### How does GitNexus handle files that match multiple framework patterns?

GitNexus evaluates patterns in priority order within `detectFrameworkFromPath()`, returning the first match found. For example, a Next.js App Router pattern ([`/app/page.tsx`](https://github.com/abhigyanpatwari/GitNexus/blob/main//app/page.tsx)) is checked before generic Express routes. If multiple frameworks use similar decorators, `detectFrameworkFromAST()` returns the first matching pattern from the `AST_PATTERNS_LOWERED` table for that specific language.

### What happens when no framework is detected?

When neither path-based nor AST-based detection returns a match, the functions return `null`. In `calculateEntryPointScore()`, this results in a neutral **framework multiplier of 1.0**, meaning the entry point score relies solely on export status, naming conventions, and call graph metrics without framework-specific boosting.

### Which programming languages and frameworks are currently supported?

GitNexus supports framework detection across multiple language ecosystems. Path-based detection covers **JavaScript/TypeScript** (Next.js, Express), **Python** (Django, FastAPI), **PHP** (Laravel), **Java**, **Kotlin**, **Go**, **Rust**, and **Swift**. AST-based detection uses language-specific pattern tables that include decorators for **NestJS**, **Actix**, **Laravel**, and other annotation-driven frameworks.

### Can developers extend framework detection for custom frameworks?

Yes. Developers can extend detection by modifying the pattern tables in [`gitnexus/src/core/ingestion/framework-detection.ts`](https://github.com/abhigyanpatwari/GitNexus/blob/main/gitnexus/src/core/ingestion/framework-detection.ts). For path-based detection, add new conditional blocks to `detectFrameworkFromPath()` returning a `FrameworkHint` with appropriate multipliers. For AST-based detection, extend `AST_PATTERNS_LOWERED` with new language entries containing framework-specific string patterns and multipliers.