Navigating Large CodebasesLesson 3.2
How to understand module architecture from import statements
import graph reading, circular dependency detection, absolute vs relative imports, index barrel files, understanding coupling, dependency direction
Imports Map the Architecture
Every import statement is an architectural declaration. The pattern of imports in a codebase reveals its layer structure, coupling problems, and design intent โ without reading a single line of implementation.
Reading an Import Block
// What does this import block tell you about app architecture?
import { Router } from 'express'; // framework dependency
import { validateRequest } from '../middleware/validate'; // lower layer
import { UserService } from '../services/user'; // business logic
import { UserRepository } from '../repositories/user'; // data access
import { User } from '../models/user'; // data shape
import { logger } from '../utils/logger'; // cross-cutting
// Reading: this is a route handler (uses Router, middleware)
// Architecture: routes โ services โ repositories โ models
// Smell: route directly imports repository โ skipping the service layerCircular Dependencies Are Red Flags
# Detect circular dependencies in Node.js
npx madge --circular src/
# Or use depcheck to find unused dependencies
npx depcheckA circular import (A imports B, B imports A) means the two modules are tightly coupled and can't be understood in isolation. They're also a common source of runtime errors in JavaScript. Finding them early during code reading saves hours of debugging later.
