# Why Cursor uses deprecated APIs

- Tool: Cursor
- Difficulty: Beginner
- Time required: 10-15 min
- Compatibility: Cursor Free+, Node.js 18+ projects
- Last updated: March 2026

## TL;DR

Cursor's training data includes older Node.js code, causing it to generate deprecated APIs like url.parse(), fs.exists(), and the domain module. By adding Node.js version rules to .cursorrules and using @docs to index current Node.js documentation, you ensure Cursor generates modern, supported API calls that will not break in future Node.js versions.

## Why Cursor uses deprecated APIs and how to fix it

Cursor's training data spans decades of Node.js code, including deprecated patterns from Node.js 8-16 era. Without version constraints, it generates url.parse() instead of new URL(), fs.existsSync() instead of fs.accessSync(), and callback-based fs methods instead of fs.promises. This tutorial pins Cursor to modern Node.js APIs.

## Before you start

- Cursor installed with a Node.js project
- Node.js 18+ installed
- package.json with engine requirements
- Familiarity with Cursor Chat (Cmd+L) and Cmd+K

## Step-by-step guide

### 1. Add Node.js version rules to .cursor/rules

Create rules that specify your Node.js version and list deprecated APIs with their modern replacements. This prevents Cursor from generating outdated code.

```
---
description: Node.js API version rules
globs: "src/**/*.ts,src/**/*.js"
alwaysApply: true
---

## Node.js Version: 22 (LTS)

## Deprecated → Modern Replacements
| Deprecated | Use Instead |
|-----------|------------|
| url.parse() | new URL() |
| querystring.parse() | URLSearchParams |
| fs.exists() | fs.access() or fs.stat() |
| fs.readFile(cb) | fs.promises.readFile() |
| Buffer(string) | Buffer.from(string) |
| util.puts() | console.log() |
| domain module | AsyncLocalStorage |
| util.isArray() | Array.isArray() |
| require() in ESM | import |
| crypto.createCipher() | crypto.createCipheriv() |

## Rules
- ALWAYS use fs.promises (import fs from 'node:fs/promises')
- ALWAYS use node: protocol prefix (node:fs, node:path, node:crypto)
- NEVER use callback-based fs methods
- Use native fetch() instead of http.request() for HTTP calls
- Use structuredClone() instead of JSON.parse(JSON.stringify())
- Use AbortController instead of manual timeout handling
```

**Expected result:** Cursor generates modern Node.js APIs matching your target version.

### 2. Index current Node.js docs with @docs

Use Cursor's @docs feature to index the latest Node.js documentation. This gives the AI current API information to reference.

```
// In Cursor Settings → Features → Docs:
// 1. Click 'Add new doc'
// 2. Enter URL: https://nodejs.org/api/
// 3. Name it: 'Node.js 22 API'
// 4. Wait for indexing to complete
//
// Now use in prompts:
// @docs:Node.js 22 API Generate a file reader using the
// current recommended fs API.
```

> Pro tip: Index specific Node.js documentation pages for the APIs you use most: fs, path, crypto, http, stream. This gives Cursor precise, current reference material.

**Expected result:** Current Node.js documentation indexed and available via @docs in prompts.

### 3. Audit existing code for deprecated APIs

Use Cursor to scan your codebase for deprecated Node.js API usage that may have been generated in earlier sessions.

```
// Cursor Chat prompt (Cmd+L, Ask mode):
// @codebase Find all uses of deprecated Node.js APIs in src/:
// 1. url.parse() → should be new URL()
// 2. querystring.parse() → should be URLSearchParams
// 3. Callback-based fs (fs.readFile with callback)
//    → should be fs.promises.readFile()
// 4. Buffer() constructor → should be Buffer.from()
// 5. require() in .ts files → should be import
// 6. fs without node: prefix → should be node:fs
// List each finding with file, line, and the modern replacement.
```

**Expected result:** A complete list of deprecated API usage across your codebase.

### 4. Replace deprecated APIs with Cmd+K

For each deprecated API found, select the code and use Cmd+K to modernize it. Cursor generates the correct modern equivalent.

```
// DEPRECATED:
const parsed = url.parse(req.url, true);
const name = parsed.query.name;

// Select and press Cmd+K:
// 'Replace url.parse with new URL(). Use Node.js 22 API.'

// MODERN:
const parsed = new URL(req.url, `http://${req.headers.host}`);
const name = parsed.searchParams.get('name');
```

**Expected result:** Deprecated API replaced with the modern equivalent.

### 5. Verify with Node.js deprecation warnings

Run your code with deprecation warnings enabled to catch any remaining deprecated API usage.

```
// Terminal: Run with deprecation warnings
NODE_OPTIONS='--throw-deprecation' npm test

// This makes Node.js throw an error (not just warn) when
// deprecated APIs are called, ensuring all are caught.
//
// Common deprecation warnings:
// DEP0005: Buffer() constructor
// DEP0025: require('sys')
// DEP0079: url.resolve()
// DEP0106: crypto.createDecipher()
```

**Expected result:** No deprecation warnings or errors, confirming all APIs are current.

## Complete code example

File: `.cursor/rules/nodejs.mdc`

```markdown
---
description: Modern Node.js API rules (Node 22 LTS)
globs: "src/**/*.{ts,js}"
alwaysApply: true
---

## Runtime: Node.js 22 LTS

## Module System
- Use ESM imports (import/export), not require()
- Use node: protocol prefix for built-ins:
  import fs from 'node:fs/promises';
  import path from 'node:path';
  import { createHash } from 'node:crypto';

## File System
- ALWAYS use fs/promises: import fs from 'node:fs/promises'
- NEVER use callback-based fs methods
- Use fs.access() to check existence, not fs.exists()
- Use fs.readFile(path, 'utf-8') for text files

## URLs and Query Strings
- Use new URL() instead of url.parse()
- Use URLSearchParams instead of querystring module
- Use URL.canParse() for validation

## HTTP
- Use native fetch() for HTTP requests (Node 21+)
- Use AbortController for timeouts
- Use node:http2 for HTTP/2 support

## Buffers
- Use Buffer.from() and Buffer.alloc()
- NEVER use new Buffer() (deprecated)

## Crypto
- Use crypto.createCipheriv(), not createCipher()
- Use crypto.randomUUID() for UUID generation
- Use crypto.subtle for WebCrypto API

## Utilities
- Use structuredClone() for deep cloning
- Use AsyncLocalStorage for request context
- Use AbortController for cancellation
- Use Array.isArray(), not util.isArray()
```

## Common mistakes

- **Cursor using require() in TypeScript files** — Cursor's training data includes vast amounts of CommonJS code. Without ESM rules, it defaults to require() even in TypeScript projects. Fix: Add 'Use ESM imports (import/export), not require()' to .cursorrules. Specify 'type: module' in package.json.
- **Cursor using callback-based fs methods** — Callback fs methods are more common in training data than fs.promises. Cursor generates them by default. Fix: Add 'ALWAYS use fs/promises' to your rules. Import as: import fs from 'node:fs/promises'
- **Missing node: protocol prefix on built-in imports** — Older Node.js code imports 'fs' instead of 'node:fs'. The node: prefix ensures the import resolves to the built-in module, not an npm package with the same name. Fix: Add 'Use node: protocol prefix for built-ins' to .cursorrules.

## Best practices

- Specify your Node.js version in .cursorrules to constrain API suggestions
- Use the node: protocol prefix for all built-in module imports
- Index current Node.js documentation with @docs for up-to-date API references
- Use fs/promises instead of callback-based fs methods
- Use new URL() and URLSearchParams instead of url.parse() and querystring
- Run with --throw-deprecation in tests to catch deprecated API usage
- Audit your codebase periodically with @codebase for deprecated patterns

## Frequently asked questions

### Why does Cursor suggest deprecated APIs?

Cursor's training data includes Node.js code from all eras. Deprecated APIs like url.parse() appear millions of times in existing code, making them the most common pattern the model has seen.

### Will deprecated APIs stop working immediately?

No. Node.js deprecates APIs gradually. Most deprecated APIs still work but emit warnings. However, they may be removed in future major versions, so migrating early is wise.

### How do I check which Node.js version I am running?

Run 'node --version' in your terminal. Update your .cursorrules to match. If your deployment targets a different version, use the deployment version in your rules.

### Can I use @docs for framework documentation too?

Yes. Index Express, Fastify, or NestJS docs alongside Node.js docs. Cursor can reference multiple doc sources in a single prompt using @docs:name syntax.

### Should I use the node: prefix for third-party packages?

No. The node: prefix is only for Node.js built-in modules. Third-party packages are imported normally: import express from 'express'.

---

Source: https://www.rapidevelopers.com/cursor-tutorial/how-to-handle-cursor-ai-suggestions-that-rely-on-soon-to-be-deprecated-node-js-apis
© RapidDev — https://www.rapidevelopers.com/cursor-tutorial/how-to-handle-cursor-ai-suggestions-that-rely-on-soon-to-be-deprecated-node-js-apis
