A comprehensive rule set for safely integrating, maintaining, and governing third-party libraries in modern applications.
You're building applications faster than ever, but every new library feels like a potential landmine. One vulnerability scan failure, one breaking update, or one bloated bundle later, and you're spending days debugging instead of shipping features. Sound familiar?
Most teams treat third-party libraries as "install and forget" - until they can't. You've probably experienced:
The typical developer workflow looks like this: npm install awesome-lib, import it everywhere, ship it, then pray nothing breaks. But what happens when awesome-lib introduces a critical CVE, or when you need to replace it with something better?
These Cursor Rules transform your dependency management from reactive firefighting to proactive governance. Instead of hoping your libraries play nice together, you get:
Think of it as infrastructure-as-code for your dependency management - repeatable, auditable, and reliable.
// Before: Wild west dependency management
import moment from 'moment';
import _ from 'lodash';
import axios from 'axios';
// After: Governed, abstracted, optimized
import { formatDate } from '@/utils/date'; // date-fns under the hood
import { debounce } from '@/utils/async'; // custom implementation
import { apiClient } from '@/services/http'; // axios behind interface
Your CI pipeline automatically scans every dependency for:
{
"sideEffects": false,
"type": "module",
"overrides": {
"*": {
"event-stream": "0.0.0"
}
}
}
Track exactly what each library costs you:
# Traditional approach: 30 minutes → potential production issues
npm install d3
# Import everywhere, discover performance issues in production
# Governed approach: 45 minutes → bulletproof integration
proposal:
author: "frontend-team"
library: "[email protected]"
motivation: "Interactive charts for analytics dashboard"
alternatives_considered: ["chart.js", "recharts"]
bundle_impact: "+45KB gzipped"
reviews:
security: "passed - no CVEs, MIT license"
architecture: "approved - will wrap in ChartService abstraction"
performance: "acceptable - lazy loaded in chart routes only"
implementation:
abstraction: "@/services/ChartService"
loading: "dynamic import on route activation"
testing: "visual regression tests + performance benchmarks"
Result: New feature ships with confidence, zero production surprises.
# Alert: [email protected] has RCE vulnerability (CVSS 9.8)
# Traditional response: Panic, manual updates, hope nothing breaks
npm update lodash
# Test everything manually, deploy with fingers crossed
# Governed response: Systematic, tested, documented
npm audit --production # Automated daily scan caught this
./scripts/security-patch.sh lodash 4.17.21
# Runs full test suite, updates SBOM, documents changes
Impact: Security patches deployed in hours, not days, with full confidence.
Swift Package Manager Integration:
// Package.swift - Exact versions, no surprises
dependencies: [
.package(url: "https://github.com/Alamofire/Alamofire.git",
exact: "5.8.1")
]
// NetworkService.swift - Abstracted, testable
protocol NetworkServiceProtocol {
func request<T: Codable>(_ endpoint: Endpoint) async throws -> T
}
class AlamofireNetworkService: NetworkServiceProtocol {
// Implementation details hidden from business logic
}
Gradle Version Catalogs:
# libs.versions.toml - Centralized, renovate-bot friendly
[versions]
okhttp = "4.12.0"
retrofit = "2.9.0"
[libraries]
okhttp = { group = "com.squareup.okhttp3", name = "okhttp", version.ref = "okhttp" }
retrofit = { group = "com.squareup.retrofit2", name = "retrofit", version.ref = "retrofit" }
# Install governance tools
npm install -D eslint-plugin-security eslint-plugin-no-unsanitized
npm install -D webpack-bundle-analyzer
# Configure package.json for deterministic builds
{
"type": "module",
"engines": { "node": ">=18" },
"scripts": {
"audit": "npm audit --production",
"deps:check": "npm outdated",
"bundle:analyze": "webpack-bundle-analyzer dist/stats.json"
}
}
// types/external.d.ts - Centralized third-party types
declare module 'awesome-lib' {
export interface AwesomeConfig {
apiKey: string;
timeout: number;
}
export function initialize(config: AwesomeConfig): Promise<void>;
}
// services/AwesomeService.ts - Your abstraction
export interface DataProcessor {
process(input: unknown): Promise<ProcessedData>;
}
class AwesomeLibProcessor implements DataProcessor {
async process(input: unknown): Promise<ProcessedData> {
// Validation, error handling, logging
const validated = await this.validateInput(input);
try {
const result = await awesomeLib.process(validated);
return this.transformResult(result);
} catch (error) {
this.logger.error('awesome-lib-error', {
library: '[email protected]',
function: 'process',
error: error.message
});
throw new ProcessingError('Data processing failed', { cause: error });
}
}
}
# .github/workflows/dependency-check.yml
name: Dependency Security Check
on: [push, pull_request]
jobs:
security-audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Security Audit
run: |
npm audit --audit-level high
npm run deps:vulnerabilities
- name: License Check
run: npm run license:verify
// webpack.config.js
module.exports = {
plugins: [
new BundleAnalyzerPlugin({
analyzerMode: process.env.ANALYZE ? 'server' : 'disabled'
})
],
optimization: {
splitChunks: {
chunks: 'all',
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all'
}
}
}
}
};
Security Posture:
Development Velocity:
Application Performance:
Before These Rules:
🔴 "We can't upgrade React because something might break"
🔴 "The security scan failed but we don't know which library"
🔴 "Our bundle is 2MB but we don't know why"
🔴 "This library worked in dev but crashes in production"
After Implementation:
✅ "React upgrade tested and deployed in 2 hours"
✅ "Security patch automatically applied and verified"
✅ "Bundle analysis shows exactly what each dependency costs"
✅ "All integrations have circuit breakers and proper error handling"
Your pull requests go from:
- Added cool-library for feature X
+ 📝 Library Proposal: [email protected]
+ 🔒 Security: No CVEs, MIT license approved
+ 📊 Bundle Impact: +12KB gzipped, lazy-loaded
+ 🏗️ Architecture: Wrapped in FeatureService abstraction
+ ✅ Testing: Unit tests + integration smoke tests added
These rules aren't just about avoiding problems - they're about building applications you can maintain and scale confidently. When your dependency management is systematic rather than ad-hoc, you ship features faster because you're not constantly firefighting library issues.
The governance workflow might seem like overhead initially, but teams report that the 15-minute proposal process saves hours of debugging later. More importantly, it creates shared knowledge about why each dependency exists and how to replace it when needed.
Your future self (and teammates) will thank you when that critical library needs an emergency replacement, and you can swap it out in minutes instead of days because you built proper abstractions from the start.
Ready to transform your dependency chaos into systematic governance? These rules turn library integration from a risk into a competitive advantage.
You are an expert in Third-Party Library Integration across JavaScript/TypeScript (npm), Kotlin/Java (Gradle), and Swift (CocoaPods).
Key Principles
- Favour minimal, well-maintained dependencies; every new library must have a clear ROI.
- Pin exact versions (no ^ or ~ in package.json) and rely on semantic versioning for upgrades.
- Isolate libraries behind thin abstraction layers to reduce coupling and allow painless replacement.
- Enforce a formal approval workflow: proposal → security review → architectural review → merge.
- Maintain a living Software Bill of Materials (SBOM) that is autogenerated on every build.
- Automate security, licence, and vulnerability scans in CI; block merges on critical issues.
- Adopt the “least-capability” principle when configuring or importing libraries (only require what you use).
- Prefer pure ES Modules / Kotlin Multiplatform / Swift Package Manager when possible to enable tree-shaking and optimise app size.
JavaScript / TypeScript
- Use import … from "pkg"; never require() in TypeScript code; enable "moduleResolution: node16".
- Declare third-party types in a dedicated global.d.ts if @types/… is unavailable.
- Group external imports at the top; one line per package; sort alphabetically.
- For side-effect libraries (e.g., polyfills) import once in the application root and document the rationale.
- Configure package.json:
"type": "module",
"engines": {"node": ">=18"},
"overrides": {"*": {"event-stream": "0.0.0"}} // explicit blocks
- Use npm ci in CI to guarantee deterministic installs using package-lock.json.
- Enable eslint-plugin-security and eslint-plugin-no-unsanitized for additional static checks.
Kotlin / Java (Gradle)
- Use Version Catalogs (libs.versions.toml) to centralise versions and enable renovate-bot automation.
- Always specify versions, never use latest.release.
- Exclude unused transitive dependencies: implementation("com.squareup.okhttp3:okhttp:4.12.0") { exclude(group = "org.jetbrains", module = "annotations") }
- Run ./gradlew dependencyUpdates –release-channel current to audit outdated libs.
- Apply the Gradle “dependency-check” plugin to fail builds on CVEs above CVSS 7.0.
Swift (CocoaPods / SPM)
- Prefer Swift Package Manager; fall back to CocoaPods only if SPM is unsupported.
- Use exactVersion("1.4.2") in Package.swift; never .upToNextMinor.
- podspecs must pin deployment_target and licence.
- Enable “Perform Single-Module Optimization” and LTO for release builds.
Error Handling and Validation
- Wrap every external call with try/catch (or Result in Kotlin) and convert low-level errors into domain-specific errors.
- Log: library-error-{libraryName} with structured metadata (version, function, params hash, stack).
- Provide circuit breakers (e.g., opossum for Node) around unstable libraries or network SDKs.
- Validate configuration objects before passing them to libraries using Zod (TS) / kotlinx.serialization (Kotlin) / Swift Codable validation.
Framework-Specific Rules
Salesforce Lightning Web Components (LWC)
- Upload minified libraries as static resources (no CDN) and reference via loadScript(this, resource).
- Gate script loading behind this.isLibLoaded boolean; handle errors via .catch(err ⇒ this.dispatchEvent(new ShowToastEvent(…))).
AMD (RequireJS/Almond)
- Name anonymous modules: define("moment", ["exports"], function (exports) { … });
- Use require.config({ paths: { moment: "vendor/moment.min" }, enforceDefine: true }) to prevent global leaks.
Additional Sections
Testing
- Mock: use jest.mock("pkg") / Mockito.when(…) / OHHTTPStubs for Swift.
- Maintain golden contract tests to detect breaking API changes during upgrades.
- Execute integration smoke tests with real library calls on nightly builds only.
Performance
- Run webpack-bundle-analyzer (JS) or gradle-profiler (Kotlin) after every dependency change.
- Strip unused code: sideEffects: false in package.json + ProGuard / R8 for Android + -dead_strip in Swift.
- Measure cold-start impact: keep Δ <100 ms per added lib.
Security
- Subscribe to GitHub Security Advisories & npm audit –production; SLA: patch critical <24 h.
- Enforce licence whitelists (MIT, Apache-2.0, BSD-3); block GPL, AGPL by policy.
- For browser scripts, enable Subresource Integrity (SRI) and Content-Security-Policy (CSP) headers.
Documentation
- Auto-generate dependency docs via npm-license-checker / gradle-license-report.
- In code, start every third-party wrapper file with JSDoc/KDoc header:
/**
* @library date-fns@^2.30.0 – ISO date utilities
* Reason: Replace moment.js (size ↓80 KB)
*/
- Maintain CHANGELOG.md entry for every upgrade with migration notes.
Governance Workflow Example (pseudo-yaml)
proposal:
author: dev
library: "[email protected]"
motivation: "smaller bundle, modern API"
reviews:
security: passed
architecture: passed
merge: allowed