Javascript AI Coding Rules

Javascript AI rules help engineering teams get better results from AI coding assistants like Cursor, Windsurf, and GitHub Copilot. By defining clear conventions for code style, architecture patterns, error handling, and module organisation, Javascript AI rules ensure that generated code is consistent, maintainable, and production-ready. Whether you are working on a side project or a large-scale enterprise system, community-curated rules on AI Rules Hub provide a solid foundation you can adopt instantly and customise to fit your team's standards.

Why Use AI Rules for Javascript?

  • Ensure AI-generated Javascript code follows your team's conventions
  • Prevent common anti-patterns that degrade maintainability
  • Reduce code review cycles by getting AI output right the first time
  • Standardise error handling, logging, and module structure
  • Make AI assistants produce secure and performance-conscious code

Best Practices for Javascript AI Coding

Define a Consistent Code Style

Specify formatting preferences (indentation, quotes, trailing commas) for Javascript so AI output matches your linter configuration without manual edits.

Enforce Error Handling Patterns

Instruct AI to always handle errors explicitly, use structured logging, and avoid swallowing exceptions silently.

Set Module Organisation Rules

Define how Javascript modules should be organised — feature folders, barrel exports, and separation of concerns — so AI keeps the project structure clean.

Require Security-Conscious Patterns

Add rules that enforce input validation, sanitisation, and safe dependency usage so AI never introduces obvious security vulnerabilities.

Common Patterns & Standards

#01

Separation of Concerns

Keep business logic, data access, and presentation layers separate in Javascript projects so each layer is independently testable.

#02

Dependency Injection

Pass dependencies explicitly through constructors or function parameters — avoiding global state that makes testing difficult.

#03

Consistent Naming Conventions

Rule AI to follow Javascript community naming standards for files, classes, functions, and constants.

#04

Automated Testing Standards

Define what test types are required (unit, integration) and where test files should live so AI generates tests alongside implementation code.

Top Javascript Rules on AI Rules Hub

Filter: JavaScript
Clear all

No description provided.

# Fastify + TypeScript + MongoDB Backend - Project Initialization Guide

> **AI Instruction**: Use this document to fully scaffold and initialize the backend project. Follow each section in order. Do not skip steps. Generate all files with the exact structure and content described.

---

## Tech Stack

| Layer | Technology |
|---|---|
| Runtime | Node.js (v20+) |
| Framework | Fastify v4 |
| Language | TypeScript (strict mode) |
| Database | MongoDB (via Mongoose v8) |
| Validation | Zod |
| Environment | dotenv |
| Dev Tooling | tsx, ts-node, eslint, prettier |

---

## Folder Structure

Generate the following folder and file structure exactly:

```
project-root/
├── src/
│   ├── config/
│   │   ├── db.ts                  # MongoDB connection logic
│   │   └── env.ts                 # Zod-validated environment variables
│   ├── modules/
│   │   └── example/
│   │       ├── example.controller.ts
│   │       ├── example.route.ts
│   │       ├── example.schema.ts  # Zod schemas
│   │       ├── example.model.ts   # Mongoose model
│   │       └── example.service.ts
│   ├── plugins/
│   │   ├── sensible.ts            # fastify-sensible plugin
│   │   └── swagger.ts             # Swagger/OpenAPI plugin (optional)
│   ├── hooks/
│   │   └── auth.hook.ts           # Global auth hooks (if needed)
│   ├── utils/
│   │   ├── logger.ts              # Custom logger wrapper
│   │   └── response.ts            # Standard API response helpers
│   ├── types/
│   │   └── index.d.ts             # Global type augmentations
│   ├── app.ts                     # Fastify app factory
│   └── server.ts                  # Entry point — starts server
├── .env
├── .env.example
├── .eslintrc.json
├── .prettierrc
├── tsconfig.json
├── package.json
└── README.md
```

---

## Step 1 — Initialize the Project

Run the following commands:

```bash
mkdir project-root && cd project-root
npm init -y
git init
```

---

## Step 2 — Install Dependencies

```bash
# Production dependencies
npm install fastify @fastify/sensible @fastify/cors mongoose zod dotenv

# Development dependencies
npm install -D typescript tsx ts-node @types/node \
  eslint prettier eslint-config-prettier \
  @typescript-eslint/parser @typescript-eslint/eslint-plugin
```

---

## Step 3 — TypeScript Configuration

**File: `tsconfig.json`**

```json
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "lib": ["ES2022"],
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "resolveJsonModule": true,
    "declaration": true,
    "declarationMap": true,
    "sourceMap": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist"]
}
```

---

## Step 4 — Package.json Scripts

Add the following `scripts` block to `package.json`:

```json
{
  "type": "module",
  "scripts": {
    "dev": "tsx watch src/server.ts",
    "build": "tsc",
    "start": "node dist/server.js",
    "lint": "eslint src --ext .ts",
    "format": "prettier --write src/**/*.ts"
  }
}
```

---

## Step 5 — Environment Variables

**File: `.env.example`**

```env
NODE_ENV=development
PORT=3000
HOST=0.0.0.0
MONGODB_URI=mongodb://localhost:27017/mydb
JWT_SECRET=your_jwt_secret_here
```

**File: `.env`** — copy from `.env.example` and fill in real values.

---

## Step 6 — Zod Environment Validation

**File: `src/config/env.ts`**

```typescript
import { z } from 'zod';
import dotenv from 'dotenv';

dotenv.config();

const envSchema = z.object({
  NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),
  PORT: z.coerce.number().default(3000),
  HOST: z.string().default('0.0.0.0'),
  MONGODB_URI: z.string().url(),
  JWT_SECRET: z.string().min(16),
});

const parsed = envSchema.safeParse(process.env);

if (!parsed.success) {
  console.error('❌ Invalid environment variables:');
  console.error(parsed.error.flatten().fieldErrors);
  process.exit(1);
}

export const env = parsed.data;
```

---

## Step 7 — MongoDB Connection

**File: `src/config/db.ts`**

```typescript
import mongoose from 'mongoose';
import { env } from './env.js';

export async function connectDB(): Promise<void> {
  try {
    await mongoose.connect(env.MONGODB_URI);
    console.log('✅ MongoDB connected');
  } catch (error) {
    console.error('❌ MongoDB connection error:', error);
    process.exit(1);
  }
}

export async function disconnectDB(): Promise<void> {
  await mongoose.disconnect();
  console.log('🔌 MongoDB disconnected');
}
```

---

## Step 8 — Fastify App Factory

**File: `src/app.ts`**

```typescript
import Fastify, { FastifyInstance } from 'fastify';
import sensible from '@fastify/sensible';
import cors from '@fastify/cors';

import { exampleRoutes } from './modules/example/example.route.js';

export async function buildApp(): Promise<FastifyInstance> {
  const app = Fastify({
    logger: {
      level: 'info',
      transport: {
        target: 'pino-pretty',
        options: { colorize: true },
      },
    },
  });

  // Plugins
  await app.register(sensible);
  await app.register(cors, { origin: true });

  // Routes
  await app.register(exampleRoutes, { prefix: '/api/v1/examples' });

  // Health check
  app.get('/health', async () => ({ status: 'ok' }));

  return app;
}
```

---

## Step 9 — Server Entry Point

**File: `src/server.ts`**

```typescript
import { buildApp } from './app.js';
import { connectDB, disconnectDB } from './config/db.js';
import { env } from './config/env.js';

async function main() {
  const app = await buildApp();

  await connectDB();

  try {
    await app.listen({ port: env.PORT, host: env.HOST });
    console.log(`🚀 Server running at http://${env.HOST}:${env.PORT}`);
  } catch (err) {
    app.log.error(err);
    await disconnectDB();
    process.exit(1);
  }

  // Graceful shutdown
  const shutdown = async (signal: string) => {
    console.log(`\n⚠️  Received ${signal}. Shutting down...`);
    await app.close();
    await disconnectDB();
    process.exit(0);
  };

  process.on('SIGINT', () => shutdown('SIGINT'));
  process.on('SIGTERM', () => shutdown('SIGTERM'));
}

main();
```

---

## Step 10 — Example Module

### Zod Schema
**File: `src/modules/example/example.schema.ts`**

```typescript
import { z } from 'zod';

export const createExampleSchema = z.object({
  name: z.string().min(1, 'Name is required').max(100),
  description: z.string().optional(),
  isActive: z.boolean().default(true),
});

export const updateExampleSchema = createExampleSchema.partial();

export const exampleParamsSchema = z.object({
  id: z.string().length(24, 'Invalid MongoDB ObjectId'),
});

export type CreateExampleInput = z.infer<typeof createExampleSchema>;
export type UpdateExampleInput = z.infer<typeof updateExampleSchema>;
export type ExampleParams = z.infer<typeof exampleParamsSchema>;
```

---

### Mongoose Model
**File: `src/modules/example/example.model.ts`**

```typescript
import mongoose, { Document, Schema } from 'mongoose';

export interface IExample extends Document {
  name: string;
  description?: string;
  isActive: boolean;
  createdAt: Date;
  updatedAt: Date;
}

const exampleSchema = new Schema<IExample>(
  {
    name: { type: String, required: true, trim: true },
    description: { type: String },
    isActive: { type: Boolean, default: true },
  },
  {
    timestamps: true,
    versionKey: false,
  }
);

export const Example = mongoose.model<IExample>('Example', exampleSchema);
```

---

### Service Layer
**File: `src/modules/example/example.service.ts`**

```typescript
import { Example, IExample } from './example.model.js';
import { CreateExampleInput, UpdateExampleInput } from './example.schema.js';

export async function getAllExamples(): Promise<IExample[]> {
  return Example.find({ isActive: true }).lean();
}

export async function getExampleById(id: string): Promise<IExample | null> {
  return Example.findById(id).lean();
}

export async function createExample(data: CreateExampleInput): Promise<IExample> {
  const example = new Example(data);
  return example.save();
}

export async function updateExample(
  id: string,
  data: UpdateExampleInput
): Promise<IExample | null> {
  return Example.findByIdAndUpdate(id, data, { new: true, runValidators: true }).lean();
}

export async function deleteExample(id: string): Promise<IExample | null> {
  return Example.findByIdAndDelete(id).lean();
}
```

---

### Controller
**File: `src/modules/example/example.controller.ts`**

```typescript
import { FastifyRequest, FastifyReply } from 'fastify';
import { CreateExampleInput, ExampleParams, UpdateExampleInput } from './example.schema.js';
import * as service from './example.service.js';

export async function getAll(req: FastifyRequest, reply: FastifyReply) {
  const data = await service.getAllExamples();
  return reply.send({ success: true, data });
}

export async function getOne(
  req: FastifyRequest<{ Params: ExampleParams }>,
  reply: FastifyReply
) {
  const item = await service.getExampleById(req.params.id);
  if (!item) return reply.notFound('Example not found');
  return reply.send({ success: true, data: item });
}

export async function create(
  req: FastifyRequest<{ Body: CreateExampleInput }>,
  reply: FastifyReply
) {
  const data = await service.createExample(req.body);
  return reply.status(201).send({ success: true, data });
}

export async function update(
  req: FastifyRequest<{ Params: ExampleParams; Body: UpdateExampleInput }>,
  reply: FastifyReply
) {
  const data = await service.updateExample(req.params.id, req.body);
  if (!data) return reply.notFound('Example not found');
  return reply.send({ success: true, data });
}

export async function remove(
  req: FastifyRequest<{ Params: ExampleParams }>,
  reply: FastifyReply
) {
  const data = await service.deleteExample(req.params.id);
  if (!data) return reply.notFound('Example not found');
  return reply.send({ success: true, message: 'Deleted successfully' });
}
```

---

### Route Registration
**File: `src/modules/example/example.route.ts`**

```typescript
import { FastifyInstance } from 'fastify';
import { zodToJsonSchema } from 'zod-to-json-schema';
import {
  createExampleSchema,
  updateExampleSchema,
  exampleParamsSchema,
} from './example.schema.js';
import * as controller from './example.controller.js';

export async function exampleRoutes(app: FastifyInstance) {
  app.get('/', { schema: { tags: ['Examples'] } }, controller.getAll);

  app.get(
    '/:id',
    { schema: { tags: ['Examples'], params: zodToJsonSchema(exampleParamsSchema) } },
    controller.getOne
  );

  app.post(
    '/',
    {
      schema: {
        tags: ['Examples'],
        body: zodToJsonSchema(createExampleSchema),
      },
    },
    controller.create
  );

  app.put(
    '/:id',
    {
      schema: {
        tags: ['Examples'],
        params: zodToJsonSchema(exampleParamsSchema),
        body: zodToJsonSchema(updateExampleSchema),
      },
    },
    controller.update
  );

  app.delete(
    '/:id',
    { schema: { tags: ['Examples'], params: zodToJsonSchema(exampleParamsSchema) } },
    controller.remove
  );
}
```

> **Note**: Install `zod-to-json-schema` with: `npm install zod-to-json-schema`

---

## Step 11 — Utility Helpers

**File: `src/utils/response.ts`**

```typescript
export function successResponse<T>(data: T, message = 'Success') {
  return { success: true, message, data };
}

export function errorResponse(message: string, errors?: unknown) {
  return { success: false, message, errors };
}
```

---

## Step 12 — ESLint & Prettier Config

**File: `.eslintrc.json`**

```json
{
  "parser": "@typescript-eslint/parser",
  "plugins": ["@typescript-eslint"],
  "extends": [
    "eslint:recommended",
    "plugin:@typescript-eslint/recommended",
    "prettier"
  ],
  "env": { "node": true, "es2022": true },
  "rules": {
    "@typescript-eslint/no-unused-vars": ["warn"],
    "@typescript-eslint/explicit-function-return-type": "off"
  }
}
```

**File: `.prettierrc`**

```json
{
  "semi": true,
  "singleQuote": true,
  "trailingComma": "es5",
  "printWidth": 100,
  "tabWidth": 2
}
```

---

## Step 13 — .gitignore

**File: `.gitignore`**

```
node_modules/
dist/
.env
*.log
.DS_Store
```

---

## Conventions & Patterns

### Adding a New Module

To add a new module (e.g., `user`), create the following files following the same pattern:

```
src/modules/user/
├── user.controller.ts
├── user.route.ts
├── user.schema.ts
├── user.model.ts
└── user.service.ts
```

Then register the route in `src/app.ts`:

```typescript
await app.register(userRoutes, { prefix: '/api/v1/users' });
```

### Validation Pattern

Always validate input using Zod schemas in the schema file. Pass type-safe inferred types to controllers and services. Never bypass Zod for request body or params.

### Error Handling

Use `reply.notFound()`, `reply.badRequest()`, and `reply.internalServerError()` from `@fastify/sensible`. Wrap async service calls in try/catch at the controller level for unexpected errors.

---

## API Endpoints (Example Module)

| Method | Path | Description |
|---|---|---|
| GET | `/health` | Health check |
| GET | `/api/v1/examples` | List all examples |
| GET | `/api/v1/examples/:id` | Get one by ID |
| POST | `/api/v1/examples` | Create new |
| PUT | `/api/v1/examples/:id` | Update by ID |
| DELETE | `/api/v1/examples/:id` | Delete by ID |

---

## Final Checklist for AI Initialization

- [ ] Run `npm install` after generating `package.json`
- [ ] Create `.env` from `.env.example` with real values
- [ ] Ensure MongoDB is running locally or provide Atlas URI
- [ ] Run `npm run dev` to verify the server starts
- [ ] Hit `GET /health` to confirm the app is live
- [ ] Check MongoDB connection log for `✅ MongoDB connected`
8 views

No description provided.

You are an expert Chrome extension developer, proficient in JavaScript/TypeScript, browser extension APIs, and web development.

Code Style and Structure
- Write clear, modular TypeScript code with proper type definitions
- Follow functional programming patterns; avoid classes
- Use descriptive variable names (e.g., isLoading, hasPermission)
- Structure files logically: popup, background, content scripts, utils
- Implement proper error handling and logging
- Document code with JSDoc comments

Architecture and Best Practices
- Strictly follow Manifest V3 specifications
- Divide responsibilities between background, content scripts and popup
- Configure permissions following the principle of least privilege
- Use modern build tools (webpack/vite) for development
- Implement proper version control and change management

Chrome API Usage
- Use chrome.* APIs correctly (storage, tabs, runtime, etc.)
- Handle asynchronous operations with Promises
- Use Service Worker for background scripts (MV3 requirement)
- Implement chrome.alarms for scheduled tasks
- Use chrome.action API for browser actions
- Handle offline functionality gracefully

Security and Privacy
- Implement Content Security Policy (CSP)
- Handle user data securely
- Prevent XSS and injection attacks
- Use secure messaging between components
- Handle cross-origin requests safely
- Implement secure data encryption
- Follow web_accessible_resources best practices

Performance and Optimization
- Minimize resource usage and avoid memory leaks
- Optimize background script performance
- Implement proper caching mechanisms
- Handle asynchronous operations efficiently
- Monitor and optimize CPU/memory usage

UI and User Experience
- Follow Material Design guidelines
- Implement responsive popup windows
- Provide clear user feedback
- Support keyboard navigation
- Ensure proper loading states
- Add appropriate animations

Internationalization
- Use chrome.i18n API for translations
- Follow _locales structure
- Support RTL languages
- Handle regional formats

Accessibility
- Implement ARIA labels
- Ensure sufficient color contrast
- Support screen readers
- Add keyboard shortcuts

Testing and Debugging
- Use Chrome DevTools effectively
- Write unit and integration tests
- Test cross-browser compatibility
- Monitor performance metrics
- Handle error scenarios

Publishing and Maintenance
- Prepare store listings and screenshots
- Write clear privacy policies
- Implement update mechanisms
- Handle user feedback
- Maintain documentation

Follow Official Documentation
- Refer to Chrome Extension documentation
- Stay updated with Manifest V3 changes
- Follow Chrome Web Store guidelines
- Monitor Chrome platform updates

Output Expectations
- Provide clear, working code examples
- Include necessary error handling
- Follow security best practices
- Ensure cross-browser compatibility
- Write maintainable and scalable code
17 views

Share Your Javascript AI Rules

Have rules that improved your Javascript workflow? Submit them to AI Rules Hub and help the community get better results from AI coding assistants.

Frequently Asked Questions

Javascript AI rules are context files (like `.cursorrules` or `AGENTS.md`) that instruct AI coding assistants to follow Javascript best practices — covering code style, architecture, error handling, and testing conventions.

Command Palette

Search for a command to run...