Skip to main content
RapidDev - Software Development Agency
cursor-tutorial

How to reuse shared utilities with Cursor

Cursor often generates duplicate utility functions instead of importing existing shared ones from a monorepo's root packages. By creating .cursor/rules with explicit import paths, referencing shared packages with @file in prompts, and structuring your monorepo so Cursor can discover shared code, you eliminate duplication and keep your codebase DRY.

What you'll learn

  • How to structure monorepo shared packages for Cursor discoverability
  • How to write .cursor/rules that enforce shared utility imports
  • How to use @file and @folder to point Cursor at shared code
  • How to prevent Cursor from duplicating existing utility functions
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Beginner6 min read10-15 minCursor Free+, any monorepo setup (npm workspaces, Turborepo, Nx)March 2026RapidDev Engineering Team
TL;DR

Cursor often generates duplicate utility functions instead of importing existing shared ones from a monorepo's root packages. By creating .cursor/rules with explicit import paths, referencing shared packages with @file in prompts, and structuring your monorepo so Cursor can discover shared code, you eliminate duplication and keep your codebase DRY.

Making Cursor aware of shared utilities in a monorepo

In monorepo setups, shared utility functions live in a common package like packages/shared or libs/utils. Cursor often does not know these exist and generates duplicate implementations. This tutorial shows you how to configure Cursor rules, reference shared packages in prompts, and structure your project so the AI always imports from the right place.

Prerequisites

  • Cursor installed with a monorepo project open
  • A shared utilities package in your monorepo (e.g., packages/shared)
  • Basic familiarity with Cursor Chat (Cmd+L) and Composer (Cmd+I)
  • Understanding of your monorepo's import path aliases

Step-by-step guide

1

Create a shared utilities index file

Ensure your shared package has a clean index file that re-exports all utilities. Cursor reads this file to understand what shared functions are available. A well-organized barrel export makes it easy for the AI to discover existing utilities.

packages/shared/src/index.ts
1// packages/shared/src/index.ts
2
3// String utilities
4export { capitalize, slugify, truncate } from './string';
5
6// Date utilities
7export { formatDate, parseISO, daysBetween } from './date';
8
9// Validation utilities
10export { isEmail, isURL, isUUID } from './validation';
11
12// HTTP utilities
13export { fetchWithRetry, buildQueryString } from './http';
14
15// Type guards
16export { isNonNull, isString, isNumber } from './guards';

Expected result: A single entry point that lists all available shared utilities for Cursor to reference.

2

Add monorepo-aware rules to .cursor/rules

Create a rule file in each sub-package that tells Cursor where shared utilities live and how to import them. This rule auto-attaches when Cursor works on files in that package.

.cursor/rules/monorepo-imports.mdc
1---
2description: Import rules for apps/web package
3globs: "apps/web/src/**/*.{ts,tsx}"
4alwaysApply: true
5---
6
7## Shared Utilities
8- ALWAYS check @packages/shared/src/index.ts before creating utility functions
9- Import shared utilities with: import { fn } from '@myorg/shared'
10- NEVER duplicate functions that already exist in packages/shared
11- Available shared utilities: capitalize, slugify, truncate, formatDate,
12 parseISO, daysBetween, isEmail, isURL, isUUID, fetchWithRetry,
13 buildQueryString, isNonNull, isString, isNumber
14
15## Import Paths
16- Shared package: @myorg/shared
17- UI components: @myorg/ui
18- Config: @myorg/config

Pro tip: List the most commonly used shared functions directly in the rule. This way Cursor knows what exists without needing to read the actual file every time.

Expected result: Cursor will check for existing shared utilities before generating new ones in any apps/web file.

3

Reference shared packages in your prompts

When asking Cursor to generate code that might need utilities, explicitly reference the shared package using @file or @folder. This gives the AI direct visibility into what already exists. Open Cmd+L and include the reference before your request.

Cursor Chat prompt
1// Cursor Chat prompt (Cmd+L):
2// @packages/shared/src/index.ts
3// @packages/shared/src/validation.ts
4// Create a registration form handler in apps/web that
5// validates email and URL inputs. Use the validation
6// functions from our shared package instead of writing
7// new ones.

Expected result: Cursor generates a handler that imports isEmail and isURL from @myorg/shared instead of reimplementing them.

4

Configure .cursorignore for monorepo performance

Large monorepos can overwhelm Cursor's indexing. Exclude build artifacts, node_modules, and unrelated packages from indexing while keeping shared packages visible. This improves performance and reduces noise in AI suggestions.

.cursorignore
1# .cursorignore (project root)
2node_modules/
3dist/
4build/
5.next/
6coverage/
7*.log
8
9# Exclude packages you never work on
10# packages/legacy-api/
11# packages/deprecated-ui/

Pro tip: Do NOT add your shared packages to .cursorignore. Cursor needs to index them to suggest correct imports.

Expected result: Cursor indexes only relevant source code, with shared packages fully visible for import suggestions.

5

Test with a new feature generation prompt

Verify the setup by asking Cursor to generate a new feature that would typically need utility functions. The AI should import from the shared package rather than creating local copies. Use Composer (Cmd+I) for a multi-file generation.

Cursor Composer prompt
1// Composer prompt (Cmd+I):
2// @packages/shared/src/index.ts Generate a new API route
3// at apps/api/src/routes/users.ts that:
4// 1. Validates email input using shared utilities
5// 2. Slugifies the username using shared utilities
6// 3. Formats dates using shared utilities
7// Import all utilities from @myorg/shared. Do not create
8// any new utility functions.

Expected result: Cursor generates the route file with correct imports from @myorg/shared and zero duplicate utility code.

Complete working example

.cursor/rules/monorepo-imports.mdc
1---
2description: Monorepo import rules and shared package awareness
3globs: "apps/*/src/**/*.{ts,tsx},packages/*/src/**/*.{ts,tsx}"
4alwaysApply: true
5---
6
7## Monorepo Structure
8This is a monorepo using npm workspaces with the following packages:
9- packages/shared utility functions, type guards, validators
10- packages/ui shared React components (Button, Modal, Input)
11- packages/config shared configuration (ESLint, TypeScript, Tailwind)
12- apps/web Next.js frontend application
13- apps/api Express.js backend API
14
15## Import Rules
16- ALWAYS check packages/shared before writing utility functions
17- Import shared utils: import { fn } from '@myorg/shared'
18- Import UI components: import { Component } from '@myorg/ui'
19- NEVER create local utility files that duplicate shared functionality
20- NEVER import directly from relative paths across packages
21 (use package names: @myorg/shared, not ../../packages/shared)
22
23## Available Shared Utilities
24- String: capitalize, slugify, truncate, camelCase, kebabCase
25- Date: formatDate, parseISO, daysBetween, isExpired
26- Validation: isEmail, isURL, isUUID, isPhoneNumber
27- HTTP: fetchWithRetry, buildQueryString, parseSearchParams
28- Guards: isNonNull, isString, isNumber, isDefined
29
30## Before Creating New Utilities
311. Search @packages/shared for existing implementation
322. If it does not exist, add it to packages/shared (not locally)
333. Export from packages/shared/src/index.ts
344. Import in consuming packages via @myorg/shared

Common mistakes when reusing shared utilities with Cursor

Why it's a problem: Adding shared packages to .cursorignore

How to avoid: Only add build artifacts and node_modules to .cursorignore. Keep all source packages indexed.

Why it's a problem: Not listing available utilities in .cursor/rules

How to avoid: Add a bulleted list of available shared functions to your monorepo-imports.mdc rule file.

Why it's a problem: Using relative import paths across packages

How to avoid: Add a rule requiring package name imports (@myorg/shared) and never relative cross-package paths.

Best practices

  • Maintain a barrel index.ts in every shared package that re-exports all public utilities
  • List available shared functions directly in .cursor/rules files for quick AI reference
  • Reference @packages/shared/src/index.ts in every prompt that may need utility functions
  • Open separate Cursor windows for different packages in very large monorepos
  • Use .cursorindexingignore for files that should not be indexed but can still be read when referenced
  • Commit .cursor/rules/ to Git so all team members get the same monorepo-aware AI behavior
  • Use Notepads to store frequently referenced shared package documentation

Still stuck?

Copy one of these prompts to get a personalized, step-by-step explanation.

ChatGPT Prompt

I have a monorepo with packages/shared containing utility functions (capitalize, slugify, isEmail, formatDate, fetchWithRetry). Generate a new Express route handler that validates user input, formats dates, and slugifies usernames. Import all utilities from @myorg/shared. Do not create duplicate utility functions.

Cursor Prompt

In Cursor Chat (Cmd+L): @packages/shared/src/index.ts @packages/shared/src/validation.ts Create a new form validation hook in apps/web/src/hooks/useFormValidation.ts that uses isEmail, isURL, and isUUID from @myorg/shared. Import from the package name, not relative paths.

Frequently asked questions

Why does Cursor keep creating duplicate utility functions?

Cursor generates duplicates when it cannot see the shared package. Reference @packages/shared/src/index.ts in your prompt and add an alwaysApply rule listing available utilities.

Should I open the whole monorepo or just one package in Cursor?

For daily work in a specific package, opening just that package is faster. For cross-package work or refactoring shared code, open the whole monorepo so Cursor can index all packages.

How do I handle tsconfig path aliases in Cursor?

Cursor reads your tsconfig.json paths. Ensure @myorg/shared is properly mapped in tsconfig.json. Reference the tsconfig in your .cursorrules if Cursor generates wrong import paths.

Can Cursor create new shared utilities automatically?

Yes. Use Composer (Cmd+I) with a prompt like: 'Add a new sanitizeHTML function to packages/shared/src/string.ts and export it from the index. Then use it in apps/web/src/components/RichText.tsx.'

What if my shared package is in a different repository?

Use @docs to index the shared package documentation. Alternatively, use a Notepad containing the shared package API surface and reference it with @notepad-name in your prompts.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.