For Package Maintainers

Export AI Rules from NPM Packages

Learn how to export AI rules from your NPM packages so users can install them with vibe-rules.

Overview

As AI becomes more integrated into development workflows, reusable AI rules and prompts are becoming valuable shared assets. By exporting rules from your NPM packages, you can help developers get up to speed with your library's best practices quickly.

vibe-rules looks for an llms export in your package that contains rule definitions compatible with various AI-powered editors.

Package Setup

1. Configure package.json

Add an llms export to your package.json:

{
"name": "my-awesome-library",
"version": "1.0.0",
"exports": {
"./llms": {
"import": "./dist/llms.mjs",
"require": "./dist/llms.cjs"
}
}
}

Note: You can also use a simple string export: "./llms": "./dist/llms.js"

2. Create Rules File

Create your rules file that exports an array of rule definitions:

ESM Example (src/llms.mjs):

// Simple string rules
const simpleRules = [
"Always use TypeScript for this library",
"Follow the established API patterns"
];
// Advanced rule objects with metadata
const advancedRules = [
{
name: "api-guidelines",
rule: "When working with our API, always validate input parameters and handle errors gracefully.",
description: "API development best practices",
alwaysApply: true,
globs: ["src/api/**/*.ts", "src/routes/**/*.ts"]
},
{
name: "testing-patterns",
rule: "Write comprehensive tests using our testing utilities. Mock external dependencies.",
description: "Testing guidelines for this library",
globs: ["**/*.test.ts", "**/*.spec.ts"]
}
];
export default [...simpleRules, ...advancedRules];

CommonJS Example (src/llms.cjs):

module.exports = [
"Always use TypeScript for this library",
{
name: "component-patterns",
rule: "Use our component composition patterns for building reusable UI elements.",
description: "Component development guidelines",
alwaysApply: false,
globs: ["src/components/**/*.tsx", "src/ui/**/*.tsx"]
}
];

Rule Format Reference

Rule Object Schema

interface PackageRuleObject {
name: string; // Rule identifier
rule: string; // The actual rule content
description?: string; // Optional description
alwaysApply?: boolean; // Apply automatically (Cursor)
globs?: string | string[]; // File patterns to match
}

name

A unique identifier for the rule. Will be prefixed with your package name when installed.

rule

The actual rule content - this is what gets applied to the editor. Can be markdown formatted.

alwaysApply (Optional)

For Cursor editor: when true, the rule is automatically applied to all files. When false or omitted, it's applied based on context.

globs (Optional)

File patterns to match. Can be a single string or array of strings. Examples: "src/**/*.ts", ["**/*.test.js", "**/*.spec.js"]

Build Process

Make sure your build process generates the llms files in the correct format and location:

# Example build script in package.json
{
"scripts": {
"build": "tsc && npm run build:llms",
"build:llms": "cp src/llms.js dist/llms.cjs && cp src/llms.mjs dist/llms.mjs"
}
}

Tip: You can also use a bundler like Rollup or esbuild to generate both CommonJS and ESM versions automatically.

Testing Your Rules

Local Testing

Test your rules locally before publishing:

# 1. Build your package
npm run build
# 2. Test the llms export
node -e "console.log(require('./dist/llms.cjs'))"
# 3. Test with vibe-rules (link your package first)
npm link
cd ../test-project
npm link your-package-name
vibe-rules install cursor your-package-name --debug

Validation

vibe-rules validates your rule exports using Zod schemas. Common issues:

Missing required fields: Make sure rule objects have name and rule properties.

Wrong export format: Export should be an array of strings/objects, not a single object.

Invalid globs: Globs should be strings or arrays of strings, not other types.

Best Practices

Clear Rule Names

Use descriptive names like "api-guidelines" or "testing-patterns" rather than generic names like "rule1".

Specific File Patterns

Use precise glob patterns to ensure rules only apply to relevant files. Avoid overly broad patterns like "**/*".

Meaningful Descriptions

Add descriptions to help users understand when and why to use each rule.

Use alwaysApply Sparingly

Only set alwaysApply: true for fundamental rules that should always be considered.

Complete Example

Example: React Component Library

// src/llms.mjs
export default [
{
name: "component-structure",
rule: `When creating components with our library:
- Use TypeScript interfaces for props
- Follow our naming conventions (PascalCase)
- Include JSDoc comments for public components
- Use our theme system for styling`,
description: "Component development guidelines",
alwaysApply: false,
globs: ["src/components/**/*.tsx", "src/ui/**/*.tsx"]
},
{
name: "testing-components",
rule: `For component testing:
- Use our custom render utility
- Test accessibility with our a11y helpers
- Mock theme provider in tests`,
description: "Component testing patterns",
globs: ["**/*.test.tsx", "**/*.stories.tsx"]
},
{
name: "performance",
rule: "Always consider performance: use React.memo for expensive components, useMemo for heavy calculations.",
description: "Performance optimization guidelines",
alwaysApply: true
}
];

Publishing

Once your rules are ready, publish your package normally:

npm publish

Users can then install your rules with:

vibe-rules install cursor your-package-name

Documentation: Consider adding a section to your README explaining that your package exports AI rules that can be installed with vibe-rules.