How CodeGraph Framework-Specific Resolution Identifies React, Express, and Laravel Patterns

CodeGraph framework-specific resolution uses a three-phase pipeline—Detect, Extract, and Resolve—to identify framework patterns by scanning project metadata, extracting specialized AST symbols, and binding ambiguous references using directory-aware heuristics.

CodeGraph's resolution engine operates after the initial AST extraction phase to map framework-specific constructs into a unified knowledge graph. By implementing dedicated FrameworkResolver classes for each supported framework, the system accurately identifies React components, Express routes, and Laravel controllers while resolving cross-references through framework-aware naming conventions.

The Three-Phase Resolution Architecture

Each framework resolver in src/resolution/frameworks/ implements a consistent three-step interface defined in src/types.ts. This architecture ensures that React, Express, and Laravel detection follow the same lifecycle while allowing framework-specific customization.

Detection Phase

The detect(context) method determines whether a project uses a specific framework by inspecting dependency manifests and file system patterns.

React detection checks package.json for react, next, or react-native dependencies, falling back to scanning for .jsx or .tsx extensions:

if (deps.react || deps.next || deps['react-native']) return true;
return allFiles.some(f => f.endsWith('.jsx') || f.endsWith('.tsx'));

Express detection looks for express, fastify, koa, or hapi in dependencies, then validates against source patterns:

if (deps.express || deps.fastify || deps.koa || deps.hapi) return true;
if (file.includes('routes') && content.includes('express')) return true;

Laravel detection verifies the presence of the artisan CLI file or the kernel at app/Http/Kernel.php:

return context.fileExists('artisan') || context.fileExists('app/Http/Kernel.php');

Extraction Phase

During the extract(filePath, content) phase, resolvers populate the graph with framework-specific nodes while the generic AST extractor runs.

React extraction in src/resolution/frameworks/react.ts identifies:

  • Component nodes: Function declarations, arrow functions, forwardRef, and memo wrappers matching patterns like function MyComp( or const MyComp = () =>
  • Hook nodes: Functions prefixed with use extracted as specialized symbols

Express extraction in src/resolution/frameworks/express.ts creates route nodes by parsing app.METHOD('/path', handler) and router.METHOD invocations using regex patterns:

/\b(app|router)\.(get|post|put|delete|patch)\s*\(\s*['"]([^'"]+)['"]\s*,\s*([^)]+)\)/g

Laravel extraction in src/resolution/frameworks/laravel.ts captures PHP route definitions from Route::METHOD('/path', handler) and Route::resource calls, storing references to controller methods and closures.

Resolution Phase

The resolve(ref, context) method binds UnresolvedRef instances to concrete nodes using framework-specific heuristics.

React resolution strategies include:

  • PascalCase identifiers: Routed to resolveComponent with preference for files in components/ directories
  • use* prefixes: Processed by resolveHook searching hooks/ directories
  • Context/Provider names: Handled by resolveContext using naming conventions

Express resolution distinguishes between:

  • Middleware references: Resolved via whitelist patterns (auth, cors, etc.) through resolveMiddleware
  • Controller methods: FooController.bar syntax triggers resolveControllerMethod searching files containing FooController
  • Service calls: FooService.baz patterns route to resolveServiceMethod

Laravel resolution handles:

  • Eloquent static calls: Model::method() resolves via resolveModelCall scanning app/Models/
  • Controller shortcuts: FooController@method resolves through resolveControllerMethod checking app/Http/Controllers/
  • Facade calls: Auth::user() and similar are marked as external references without local nodes

All resolution helpers utilize the generic name-based lookup API (context.getNodesByName, context.getNodesInFile) biased by directory heuristics, returning ResolvedRef objects with confidence scores between 0.8 and 0.9.

Framework-Specific Detection Strategies

CodeGraph employs distinct detection heuristics for each framework ecosystem to minimize false positives while ensuring zero-configuration setup.

React Detection Heuristics

The React resolver prioritizes dependency analysis over file extension scanning. It examines package.json for React ecosystem packages including react, next, and react-native. If dependencies are inconclusive, the system falls back to scanning the project for .jsx and .tsx file extensions, making it effective for both Next.js applications and React Native mobile projects.

Express Detection Heuristics

Express detection casts a wider net to capture popular Node.js server frameworks. Beyond checking for express, the resolver recognizes fastify, koa, and hapi as valid server framework indicators. When dependency checks fail, the system analyzes file paths for Express-specific directory names (routes, controllers, middleware) and scans file contents for strings like express, app.get, or router.get.

Laravel Detection Heuristics

Laravel detection relies on framework-specific file signatures rather than package management files. The resolver checks for the artisan console entry point or the HTTP kernel at app/Http/Kernel.php, providing reliable detection regardless of whether dependencies are vendored or committed to the repository.

Extracting Framework Symbols

Each framework resolver contributes specialized node types to the knowledge graph that generic AST extraction cannot identify.

React Component and Hook Extraction

In src/resolution/frameworks/react.ts, the extraction logic uses regex patterns to distinguish between standard functions and React-specific constructs. The system identifies:

  • Function components through declaration patterns (function ComponentName, const ComponentName =)
  • Higher-order components via forwardRef and memo wrappers
  • Custom hooks through the use prefix convention

These nodes are emitted with metadata indicating their React-specific roles, enabling downstream queries to filter for component hierarchies separate from utility functions.

Express Route Extraction

The Express resolver in src/resolution/frameworks/express.ts transforms route registrations into queryable graph nodes. By parsing method chains like app.get('/users/:id', handler), the extractor creates route nodes capturing the HTTP method, path pattern, and a reference to the handler expression. This allows CodeGraph to map API endpoints to their implementing controller functions across the codebase.

Laravel Route Extraction

The Laravel resolver handles PHP's static method syntax, extracting Route::get, Route::post, and Route::resource declarations into structured route nodes. Unlike Express, Laravel routes often reference controllers using string syntax (ControllerName@method), which the extractor captures as unresolved references destined for the resolution phase.

Resolving Ambiguous References

Framework-specific resolution shines when binding ambiguous identifiers to concrete implementations using directory conventions and naming patterns.

React Reference Resolution

When CodeGraph encounters an unresolved PascalCase identifier in JSX or React code, the React resolver applies directory heuristics to locate the component definition. The system prioritizes files within components/ or src/components/ directories, then falls back to global name matching. Hook references follow similar logic but bias toward hooks/ directories. This heuristic approach resolves imports even when explicit import statements are missing or dynamically loaded.

Express Middleware and Controller Resolution

Express resolution distinguishes between middleware functions and business logic through pattern matching. Common middleware names (cors, helmet, morgan) are resolved via whitelist lookups, while dot-notation references (UserController.index) trigger controller-specific resolution that searches for class definitions or object exports matching the prefix. Service method calls follow identical patterns, enabling CodeGraph to trace a request from route definition through middleware stack to final handler.

Laravel Model and Controller Resolution

Laravel resolution leverages the framework's directory conventions to resolve static method calls. When encountering User::find(1), the resolver searches app/Models/ for a User class definition. Controller references using the @ syntax resolve by scanning app/Http/Controllers/ for the matching class and method combination. Facade calls like Auth::user() are intentionally marked as external references since they resolve to framework internals outside the project scope.

Implementing Framework Resolution in CodeGraph

The resolution pipeline integrates seamlessly with the CodeGraph API. The following example demonstrates initializing the resolution engine and querying framework-specific nodes:

import { CodeGraph } from 'codegraph';

// Initialize and index a React project
const cg = new CodeGraph({ projectRoot: '/path/to/react-app' });
await cg.init();               
await cg.indexAll();           

// Query for a specific React component
const component = await cg.graph.queryNode({
  kind: 'component',
  name: 'Header',               
});
console.log(component?.qualifiedName);

// Resolve outstanding references
const unresolved = await cg.graph.getUnresolvedRefs();
const resolved = await cg.resolution.resolveAll(); 
console.log(resolved.length, 'references resolved');

For Express applications, the identical API exposes route nodes extracted by the framework resolver:

const expressCg = new CodeGraph({ projectRoot: '/path/to/express-api' });
await expressCg.init();
await expressCg.indexAll();

const route = await expressCg.graph.queryNode({
  kind: 'route',
  name: '/users',               
});
console.log(route?.qualifiedName);

The CodeGraph class automatically registers appropriate resolvers based on detection results, requiring no manual configuration to enable framework-specific analysis.

Summary

  • Three-phase architecture: CodeGraph resolution operates through Detect, Extract, and Resolve phases implemented in src/resolution/frameworks/
  • Zero-configuration detection: Each framework resolver automatically identifies projects by scanning package.json dependencies (React/Express) or framework-specific files like artisan (Laravel)
  • Specialized node extraction: Resolvers create framework-specific nodes including React components, Express routes, and Laravel controllers that generic AST parsing cannot identify
  • Directory-aware heuristics: Resolution biases results using framework conventions like components/, app/Models/, and app/Http/Controllers/ to bind ambiguous references
  • Confidence scoring: All resolved references include confidence scores (0.8–0.9) indicating the reliability of the heuristic match

Frequently Asked Questions

How does CodeGraph detect which frameworks a project uses?

CodeGraph runs the detect(context) method for each framework resolver during initialization. React detection checks package.json for react, next, or react-native dependencies and falls back to .jsx/.tsx file scanning. Express detection looks for server framework dependencies (express, fastify, koa, hapi) and validates against source file patterns. Laravel detection verifies the presence of the artisan CLI file or app/Http/Kernel.php. All detection occurs automatically before extraction begins.

What types of nodes does CodeGraph extract for React applications?

The React resolver in src/resolution/frameworks/react.ts extracts component nodes for function components, arrow functions, and forwardRef/memo wrappers, plus function nodes for custom hooks. These specialized nodes capture React-specific metadata that distinguishes components from utility functions, enabling queries for component hierarchies and hook dependencies separate from standard JavaScript functions.

How does CodeGraph resolve controller method references in Express?

When the Express resolver encounters references like UserController.index or userController.getUser, it invokes resolveControllerMethod to search for files containing the controller name. The resolution weights results by directory location, favoring files in controllers/ folders. For middleware references such as auth or cors, the resolver uses a whitelist pattern to identify common Express middleware functions and bind them to their implementations.

Can CodeGraph resolve Laravel facade calls like Auth::user()?

Laravel facade calls are explicitly handled as external references with no local node resolution. When the Laravel resolver encounters patterns like Auth::user() or Cache::get() in src/resolution/frameworks/laravel.ts, it marks these as external framework calls rather than attempting local resolution. This reflects Laravel's architecture where facades proxy to service container bindings that may resolve to framework internals or vendor packages outside the project's source graph.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →