typescript-circular-dependency
Detect and resolve TypeScript/JavaScript circular import dependencies. Use when: (1) "Cannot access 'X' before initialization" at runtime, (2) Import returns undefined unexpectedly, (3) "ReferenceError: Cannot access X before initialization", (4) Type errors that disappear when you change import order, (5) Jest/Vitest tests fail with undefined imports that work in browser.
Install
mkdir -p .claude/skills/typescript-circular-dependency && curl -L -o skill.zip "https://mcp.directory/api/skills/download/5306" && unzip -o skill.zip -d .claude/skills/typescript-circular-dependency && rm skill.zipInstalls to .claude/skills/typescript-circular-dependency
About this skill
TypeScript Circular Dependency Detection and Resolution
Problem
Circular dependencies occur when module A imports from module B, which imports
(directly or indirectly) from module A. TypeScript compiles successfully, but at
runtime, one of the imports evaluates to undefined because the module hasn't
finished initializing yet.
Context / Trigger Conditions
Common error messages:
ReferenceError: Cannot access 'UserService' before initialization
TypeError: Cannot read properties of undefined (reading 'create')
TypeError: (0 , _service.doSomething) is not a function
Symptoms that suggest circular imports:
- Import is
undefinedeven though the export exists - Error only appears at runtime, not during TypeScript compilation
- Moving an import statement changes which import is undefined
- Tests fail but the app works (or vice versa)
- Adding
console.logat the top of a file changes behavior
Solution
Step 1: Detect the Cycle
Use a tool to visualize dependencies:
# Install madge
npm install -g madge
# Find circular dependencies
madge --circular --extensions ts,tsx src/
# Generate visual graph
madge --circular --image graph.svg src/
Or use the TypeScript compiler:
# Check for cycles (requires tsconfig setting)
npx tsc --listFiles | head -50
Step 2: Identify the Pattern
Common circular dependency patterns:
Pattern A: Service-to-Service
services/userService.ts → services/orderService.ts → services/userService.ts
Pattern B: Type imports
types/user.ts → types/order.ts → types/user.ts
Pattern C: Index barrel files
components/index.ts → components/Button.tsx → components/index.ts
Step 3: Resolution Strategies
Strategy 1: Extract Shared Dependencies
Before:
// userService.ts
import { OrderService } from './orderService';
export class UserService { ... }
// orderService.ts
import { UserService } from './userService';
export class OrderService { ... }
After:
// types/interfaces.ts (new file - no imports from services)
export interface IUserService { ... }
export interface IOrderService { ... }
// userService.ts
import { IOrderService } from '../types/interfaces';
export class UserService implements IUserService { ... }
Strategy 2: Dependency Injection
// orderService.ts
export class OrderService {
constructor(private userService: IUserService) {}
// Instead of importing UserService directly
}
// main.ts
const userService = new UserService();
const orderService = new OrderService(userService);
Strategy 3: Dynamic Imports
// Only import when needed, not at module level
async function processOrder() {
const { UserService } = await import('./userService');
// ...
}
Strategy 4: Use Type-Only Imports
If you only need types (not values), use type-only imports:
// This doesn't create a runtime dependency
import type { User } from './userService';
Strategy 5: Restructure Barrel Files
Before (problematic):
// components/index.ts
export * from './Button';
export * from './Modal'; // Modal imports Button from './index'
After:
// components/Modal.tsx
import { Button } from './Button'; // Direct import, not from index
Step 4: Prevent Future Cycles
Add to your CI/build process:
// package.json
{
"scripts": {
"check:circular": "madge --circular --extensions ts,tsx src/"
}
}
Or configure ESLint:
// .eslintrc.js
module.exports = {
plugins: ['import'],
rules: {
'import/no-cycle': ['error', { maxDepth: 10 }]
}
}
Verification
- Run
madge --circular src/- should report no cycles - Run your test suite - previously undefined imports should work
- Delete
node_modulesand reinstall - app should still work - Build for production - no runtime errors
Example
Problem: OrderService is undefined when imported in UserService
Detection:
$ madge --circular src/
Circular dependencies found!
src/services/userService.ts → src/services/orderService.ts → src/services/userService.ts
Fix: Extract shared interface
// NEW: src/types/services.ts
export interface IOrderService {
createOrder(userId: string): Promise<Order>;
}
// MODIFIED: src/services/userService.ts
import type { IOrderService } from '../types/services';
export class UserService {
constructor(private orderService: IOrderService) {}
}
// MODIFIED: src/services/orderService.ts
// No longer imports UserService
export class OrderService implements IOrderService {
async createOrder(userId: string): Promise<Order> { ... }
}
Notes
- TypeScript
import typeis your friend—it's erased at runtime and can't cause cycles - Barrel files (
index.ts) are a common source of accidental cycles - The order of exports in a file can matter when there's a cycle
- Jest/Vitest may handle module resolution differently than your bundler
- Some bundlers (Webpack, Vite) have better cycle handling than others
require()can sometimes mask circular dependency issues thatimportexposes
More by blader
View all skills by blader →You might also like
flutter-development
aj-geddes
Build beautiful cross-platform mobile apps with Flutter and Dart. Covers widgets, state management with Provider/BLoC, navigation, API integration, and material design.
drawio-diagrams-enhanced
jgtolentino
Create professional draw.io (diagrams.net) diagrams in XML format (.drawio files) with integrated PMP/PMBOK methodologies, extensive visual asset libraries, and industry-standard professional templates. Use this skill when users ask to create flowcharts, swimlane diagrams, cross-functional flowcharts, org charts, network diagrams, UML diagrams, BPMN, project management diagrams (WBS, Gantt, PERT, RACI), risk matrices, stakeholder maps, or any other visual diagram in draw.io format. This skill includes access to custom shape libraries for icons, clipart, and professional symbols.
ui-ux-pro-max
nextlevelbuilder
"UI/UX design intelligence. 50 styles, 21 palettes, 50 font pairings, 20 charts, 8 stacks (React, Next.js, Vue, Svelte, SwiftUI, React Native, Flutter, Tailwind). Actions: plan, build, create, design, implement, review, fix, improve, optimize, enhance, refactor, check UI/UX code. Projects: website, landing page, dashboard, admin panel, e-commerce, SaaS, portfolio, blog, mobile app, .html, .tsx, .vue, .svelte. Elements: button, modal, navbar, sidebar, card, table, form, chart. Styles: glassmorphism, claymorphism, minimalism, brutalism, neumorphism, bento grid, dark mode, responsive, skeuomorphism, flat design. Topics: color palette, accessibility, animation, layout, typography, font pairing, spacing, hover, shadow, gradient."
godot
bfollington
This skill should be used when working on Godot Engine projects. It provides specialized knowledge of Godot's file formats (.gd, .tscn, .tres), architecture patterns (component-based, signal-driven, resource-based), common pitfalls, validation tools, code templates, and CLI workflows. The `godot` command is available for running the game, validating scripts, importing resources, and exporting builds. Use this skill for tasks involving Godot game development, debugging scene/resource files, implementing game systems, or creating new Godot components.
nano-banana-pro
garg-aayush
Generate and edit images using Google's Nano Banana Pro (Gemini 3 Pro Image) API. Use when the user asks to generate, create, edit, modify, change, alter, or update images. Also use when user references an existing image file and asks to modify it in any way (e.g., "modify this image", "change the background", "replace X with Y"). Supports both text-to-image generation and image-to-image editing with configurable resolution (1K default, 2K, or 4K for high resolution). DO NOT read the image file first - use this skill directly with the --input-image parameter.
fastapi-templates
wshobson
Create production-ready FastAPI projects with async patterns, dependency injection, and comprehensive error handling. Use when building new FastAPI applications or setting up backend API projects.
Related MCP Servers
Browse all serversSupercharge browser tasks with Browser MCP—AI-driven, local browser automation for powerful, private testing. Inspired b
By Sentry. MCP server and CLI that provides tools for AI agents working on iOS and macOS Xcode projects. Build, test, li
Automate Excel file tasks without Microsoft Excel using openpyxl and xlsxwriter for formatting, formulas, charts, and ad
Access shadcn/ui v4 components, blocks, and demos for rapid React UI library development. Seamless integration and sourc
Context Portal: Manage project memory with a database-backed system for decisions, tracking, and semantic search via a k
TypeScript Refactoring offers advanced TypeScript/JavaScript code analysis and intelligent refactoring for seamless and
Stay ahead of the MCP ecosystem
Get weekly updates on new skills and servers.