Monorepo Support
LogicStamp Context works seamlessly with monorepos containing both backend and frontend code. Each file is analyzed independently, so you can mix Express.js, NestJS, React, Vue, and TypeScript files in the same codebase.
How It Works
LogicStamp analyzes each file independently:
- Scans all
.tsand.tsxfiles recursively (Vue.vueSFC support is upcoming) - Detects framework per file (Express, NestJS, React, Vue, or TypeScript)
- Extracts appropriate metadata based on detected framework
- Generates contracts for all files, preserving your directory structure
Key point: Files don't interfere with each other. A backend file in one folder doesn't affect frontend extraction in another folder.
Framework Detection Per File
Each file is analyzed independently with framework detection:
Priority Order
- Backend (Express/NestJS detected) →
node:api - Vue (Vue import + Vue component patterns) →
vue:componentorvue:composable - React (React import or JSX/TSX + React patterns) →
react:componentorreact:hook - TypeScript module (no framework patterns) →
ts:module
Detection Logic
- Express.js: Requires
expressimport AND route patterns (app.get(),router.post(), etc.) - NestJS: Requires
@nestjsimport AND controller decorators (@Controller(),@Get(), etc.)- Note: Only NestJS controllers/routes are extracted as
node:api. Providers/services without route decorators are treated asts:module.
- Note: Only NestJS controllers/routes are extracted as
- Vue: Requires
vueimport AND Vue component patterns (e.g.,defineComponent,createApp,setup(),computed,refusage in component context, or exports a component-ish default/object) - React: Detected by React import OR JSX/TSX + React patterns (hooks, component export, etc.)
- TypeScript module: Fallback when no framework patterns are found (React is NOT the default fallback)
Monorepo Structure Examples
Example 1: Packages-Based Monorepo
my-monorepo/
├── packages/
│ ├── backend/
│ │ └── src/
│ │ ├── routes/
│ │ │ └── users.ts → ✅ node:api (Express routes)
│ │ └── controllers/
│ │ └── posts.ts → ✅ node:api (NestJS controller)
│ │
│ ├── frontend/
│ │ └── src/
│ │ ├── components/
│ │ │ └── Button.tsx → ✅ react:component
│ │ └── hooks/
│ │ └── useAuth.ts → ✅ react:hook
│ │
│ └── shared/
│ └── types.ts → ✅ ts:moduleResult: All files are extracted correctly:
- Backend files →
backend.routes,backend.controller - Frontend files →
hooks,components,props - Shared files →
functions,imports
Example 2: Apps-Based Monorepo
my-monorepo/
├── apps/
│ ├── api/
│ │ └── src/
│ │ ├── routes.ts → ✅ node:api (Express)
│ │ └── middleware.ts → ✅ ts:module
│ │
│ └── web/
│ └── src/
│ ├── pages/
│ │ └── Home.tsx → ✅ react:component
│ └── components/
│ └── Header.tsx → ✅ react:component
│
└── packages/
└── ui/
└── Button.tsx → ✅ react:componentResult: Each app and package is analyzed independently.
Example 3: Mixed Structure
my-project/
├── server/
│ └── routes/
│ └── api.ts → ✅ node:api (Express)
│
├── client/
│ └── components/
│ └── App.tsx → ✅ react:component
│
└── shared/
└── utils.ts → ✅ ts:moduleResult: Works perfectly - no configuration needed.
Usage
Scan Entire Monorepo
# From monorepo root
stamp context
# Or specify a path
stamp context ./packagesScan Specific Packages
# Backend only
stamp context ./packages/backend
# Frontend only
stamp context ./packages/frontend
# Both (from root)
stamp contextOutput Structure
LogicStamp preserves your directory structure:
my-monorepo/
├── packages/
│ ├── backend/
│ │ └── src/
│ │ └── routes/
│ │ └── context.json ← Backend contracts
│ │
│ └── frontend/
│ └── src/
│ └── components/
│ └── context.json ← Frontend contracts
│
└── context_main.json ← Index of all foldersWhat Gets Extracted
Backend Files
Files with Express.js or NestJS patterns:
// packages/backend/src/routes/users.ts
import express from 'express';
const router = express.Router();
router.get('/users', getUsers);Extracted:
kind: "node:api"backend.routes: [{ path: '/users', method: 'GET', ... }]backend.framework: "express"apiSignature: { parameters, returnType, ... }
Frontend Files
Files with React or Vue patterns:
// packages/frontend/src/components/Button.tsx
import { useState } from 'react';
export function Button() {
const [count, setCount] = useState(0);
return <button>{count}</button>;
}Extracted:
kind: "react:component"hooks: ['useState']components: ['Button']props: { ... }state: { count: 'number' }
TypeScript Modules
Files without framework patterns:
// packages/shared/utils.ts
export function formatDate(date: Date): string {
return date.toISOString();
}Extracted:
kind: "ts:module"functions: ['formatDate']imports: [...]
Framework Detection Details
Express.js Detection
Requires both:
- Express import:
import express from 'express' - Route patterns:
app.get(),router.post(), etc.
// ✅ Detected as Express
import express from 'express';
app.get('/users', handler);
// ❌ Not detected (no route patterns)
import express from 'express';
const app = express(); // No routes definedNestJS Detection
Requires both:
- NestJS import:
import { Controller } from '@nestjs/common' - Controller decorators:
@Controller(),@Get(), etc.
Important: Only NestJS controllers/routes are extracted as node:api. Providers/services without route decorators are treated as ts:module.
// ✅ Detected as NestJS (node:api)
import { Controller } from '@nestjs/common';
@Controller('users')
export class UsersController { }
// ❌ Not detected (no controller decorators) → ts:module
import { Injectable } from '@nestjs/common';
@Injectable()
export class UsersService { }Vue Detection
Requires both:
- Vue import:
import { ref } from 'vue'orimport { ... } from 'vue/...' - Vue component patterns:
defineComponent,createApp,setup(),computed,refusage in component context, OR exports a component-ish default/object
// ✅ Detected as Vue (has import + patterns)
import { ref, defineComponent } from 'vue';
export default defineComponent({ ... });
// ❌ Not detected (has import but no component patterns) → ts:module
import { ref } from 'vue';
export function useSharedUtil() { return ref(0); } // Shared util, not a componentReact Detection
Detected by React import OR JSX/TSX + React patterns (hooks, component export, etc.):
// ✅ Detected as React (has React import + JSX)
import { useState } from 'react';
export function Component() { return <div>...</div>; }
// ✅ Detected as React (has JSX even without explicit import)
export function Component() { return <div>...</div>; }
// ❌ Not detected (no React patterns) → ts:module
export function utility() { return 'hello'; }Note: React is NOT the default fallback. Files without framework patterns become ts:module.
Best Practices
1. Separate Backend and Frontend Files
Recommended: Keep backend and frontend code in separate files:
✅ Good:
packages/backend/src/routes/users.ts → Backend routes
packages/frontend/src/components/App.tsx → Frontend component
❌ Avoid:
src/mixed.ts → Both backend routes and React componentsWhy: LogicStamp uses priority-based detection. If a file has multiple framework patterns, only one will be extracted based on priority: Backend > Vue > React. Files without framework patterns become ts:module.
2. Use Clear File Organization
Organize by concern:
✅ Good:
packages/
backend/
routes/
controllers/
frontend/
components/
hooks/
shared/
types/
utils/
❌ Less ideal:
src/
everything.ts ← Mixed concerns3. Framework-Specific Folders
Group files by framework:
✅ Good:
packages/
express-api/
nestjs-api/
react-app/
vue-app/
❌ Less ideal:
packages/
api/
express.ts
nestjs.ts
react.ts ← Mixed frameworks in same folderCommon Patterns
Next.js Monorepo
my-monorepo/
├── apps/
│ ├── web/ → Next.js app
│ │ └── app/
│ │ └── page.tsx → ✅ react:component (with Next.js metadata)
│ │
│ └── api/ → Express API
│ └── routes.ts → ✅ node:apiNote: Next.js route handlers (app/api/route.ts) are currently treated as ts:module unless Express/NestJS patterns are detected. They may be detected as react:component if they contain React patterns (JSX, hooks, etc.), but route handlers without React patterns default to ts:module.
Full-Stack Monorepo
my-monorepo/
├── server/
│ └── src/
│ ├── routes.ts → ✅ node:api (Express)
│ └── services.ts → ✅ ts:module
│
├── client/
│ └── src/
│ ├── App.tsx → ✅ react:component
│ └── hooks/
│ └── useAuth.ts → ✅ react:hook
│
└── shared/
└── types.ts → ✅ ts:moduleTroubleshooting
Files Not Detected as Backend
Problem: Express/NestJS files are detected as ts:module instead of node:api.
Solution: Ensure both conditions are met:
- ✅ Framework import exists
- ✅ Route/controller patterns exist
// ❌ Missing route patterns
import express from 'express';
const app = express(); // No routes → detected as ts:module
// ✅ Has route patterns
import express from 'express';
const app = express();
app.get('/users', handler); // Has routes → detected as node:apiMixed Files
Problem: File has both backend routes and frontend components.
Solution: Split into separate files:
// ❌ Mixed file
import express from 'express';
import { useState } from 'react';
app.get('/api', handler); // Backend
function Component() { } // Frontend
// Only backend extracted (priority)
// ✅ Separate files
// routes.ts → Backend only
// Component.tsx → Frontend onlyRelated Documentation
- Express.js Support - Express.js framework details
- NestJS Support - NestJS framework details
- React Support - React framework details
- Vue Support - Vue framework details
- CLI Usage - Command-line usage
Next Steps
Explore framework guides or initialize LogicStamp from your monorepo root.