Back to skills
SkillHub ClubShip Full StackFull StackBackendTesting

moai-lang-javascript

JavaScript ES2024+ development specialist covering Node.js 22 LTS, modern runtimes (Deno, Bun), testing (Vitest, Jest), linting (ESLint 9, Biome), and backend frameworks (Express, Fastify, Hono). Use when developing JavaScript APIs, web applications, or Node.js projects.

Packaged view

This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.

Stars
0
Hot score
74
Updated
March 20, 2026
Overall rating
C2.6
Composite score
2.6
Best-practice grade
B73.6

Install command

npx @skill-hub/cli install junseokandylee-claudeautomate-moai-lang-javascript

Repository

junseokandylee/ClaudeAutomate

Skill path: .claude/skills/moai-lang-javascript

JavaScript ES2024+ development specialist covering Node.js 22 LTS, modern runtimes (Deno, Bun), testing (Vitest, Jest), linting (ESLint 9, Biome), and backend frameworks (Express, Fastify, Hono). Use when developing JavaScript APIs, web applications, or Node.js projects.

Open repository

Best for

Primary workflow: Ship Full Stack.

Technical facets: Full Stack, Backend, Testing.

Target audience: everyone.

License: Unknown.

Original source

Catalog source: SkillHub Club.

Repository owner: junseokandylee.

This is still a mirrored public skill entry. Review the repository before installing into production workflows.

What it helps with

  • Install moai-lang-javascript into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
  • Review https://github.com/junseokandylee/ClaudeAutomate before adding moai-lang-javascript to shared team environments
  • Use moai-lang-javascript for development workflows

Works across

Claude CodeCodex CLIGemini CLIOpenCode

Favorites: 0.

Sub-skills: 0.

Aggregator: No.

Original source / Raw SKILL.md

---
name: moai-lang-javascript
description: JavaScript ES2024+ development specialist covering Node.js 22 LTS, modern runtimes (Deno, Bun), testing (Vitest, Jest), linting (ESLint 9, Biome), and backend frameworks (Express, Fastify, Hono). Use when developing JavaScript APIs, web applications, or Node.js projects.
version: 1.0.0
updated: 2025-12-22
status: active
allowed-tools: Read, Grep, Glob, Bash, mcp__context7__resolve-library-id, mcp__context7__get-library-docs
---

## Quick Reference (30 seconds)

JavaScript ES2024+ Development Specialist - Modern JavaScript with Node.js 22 LTS, multiple runtimes, and contemporary tooling.

Auto-Triggers: `.js`, `.mjs`, `.cjs` files, `package.json`, Node.js projects, JavaScript discussions

Core Stack:
- ES2024+: Set methods, Promise.withResolvers, immutable arrays, import attributes
- Node.js 22 LTS: Native TypeScript, built-in WebSocket, stable watch mode
- Runtimes: Node.js 20/22 LTS, Deno 2.x, Bun 1.x
- Testing: Vitest, Jest, Node.js test runner
- Linting: ESLint 9 flat config, Biome
- Bundlers: Vite, esbuild, Rollup
- Frameworks: Express, Fastify, Hono, Koa

Quick Commands:
```bash
# Create Vite project
npm create vite@latest my-app -- --template vanilla

# Initialize with modern tooling
npm init -y && npm install -D vitest eslint @eslint/js

# Run with Node.js watch mode
node --watch server.js

# Run TypeScript directly in Node.js 22+
node --experimental-strip-types app.ts
```

---

## Implementation Guide (5 minutes)

### ES2024 Key Features

Set Operations:
```javascript
const setA = new Set([1, 2, 3, 4]);
const setB = new Set([3, 4, 5, 6]);

setA.intersection(setB);      // Set {3, 4}
setA.union(setB);             // Set {1, 2, 3, 4, 5, 6}
setA.difference(setB);        // Set {1, 2}
setA.symmetricDifference(setB); // Set {1, 2, 5, 6}
setA.isSubsetOf(setB);        // false
setA.isSupersetOf(setB);      // false
setA.isDisjointFrom(setB);    // false
```

Promise.withResolvers():
```javascript
function createDeferred() {
  const { promise, resolve, reject } = Promise.withResolvers();
  return { promise, resolve, reject };
}

const deferred = createDeferred();
setTimeout(() => deferred.resolve('done'), 1000);
const result = await deferred.promise;
```

Immutable Array Methods:
```javascript
const original = [3, 1, 4, 1, 5];

// New methods return new arrays (don't mutate)
const sorted = original.toSorted();           // [1, 1, 3, 4, 5]
const reversed = original.toReversed();       // [5, 1, 4, 1, 3]
const spliced = original.toSpliced(1, 2, 9);  // [3, 9, 1, 5]
const changed = original.with(2, 99);         // [3, 1, 99, 1, 5]

console.log(original); // [3, 1, 4, 1, 5] - unchanged
```

Object.groupBy and Map.groupBy:
```javascript
const items = [
  { type: 'fruit', name: 'apple' },
  { type: 'vegetable', name: 'carrot' },
  { type: 'fruit', name: 'banana' },
];

const grouped = Object.groupBy(items, item => item.type);
// { fruit: [{...}, {...}], vegetable: [{...}] }

const mapGrouped = Map.groupBy(items, item => item.type);
// Map { 'fruit' => [...], 'vegetable' => [...] }
```

### ES2025 Features

Import Attributes (JSON Modules):
```javascript
import config from './config.json' with { type: 'json' };
import styles from './styles.css' with { type: 'css' };

console.log(config.apiUrl);
```

RegExp.escape:
```javascript
const userInput = 'hello (world)';
const safePattern = RegExp.escape(userInput);
// "hello\\ \\(world\\)"
const regex = new RegExp(safePattern);
```

### Node.js 22 LTS Features

Built-in WebSocket Client:
```javascript
const ws = new WebSocket('wss://example.com/socket');

ws.addEventListener('open', () => {
  ws.send(JSON.stringify({ type: 'hello' }));
});

ws.addEventListener('message', (event) => {
  const data = JSON.parse(event.data);
  console.log('Received:', data);
});
```

Native TypeScript Support (Experimental):
```bash
# Run .ts files directly in Node.js 22.6+
node --experimental-strip-types app.ts

# In Node.js 22.18+, type stripping is enabled by default
node app.ts
```

Watch Mode (Stable):
```bash
# Auto-restart on file changes
node --watch server.js

# Watch specific files
node --watch-path=./src --watch-path=./config server.js
```

Permission Model:
```bash
# Restrict file system access
node --permission --allow-fs-read=/app/data server.js

# Restrict network access
node --permission --allow-net=api.example.com server.js
```

### Backend Frameworks

Express (Traditional):
```javascript
import express from 'express';

const app = express();
app.use(express.json());

app.get('/api/users', async (req, res) => {
  const users = await db.users.findAll();
  res.json(users);
});

app.post('/api/users', async (req, res) => {
  const user = await db.users.create(req.body);
  res.status(201).json(user);
});

app.listen(3000, () => console.log('Server running on port 3000'));
```

Fastify (High Performance):
```javascript
import Fastify from 'fastify';

const fastify = Fastify({ logger: true });

const userSchema = {
  body: {
    type: 'object',
    required: ['name', 'email'],
    properties: {
      name: { type: 'string', minLength: 2 },
      email: { type: 'string', format: 'email' },
    },
  },
};

fastify.post('/api/users', { schema: userSchema }, async (request, reply) => {
  const user = await db.users.create(request.body);
  return reply.code(201).send(user);
});

await fastify.listen({ port: 3000 });
```

Hono (Edge-First):
```javascript
import { Hono } from 'hono';
import { cors } from 'hono/cors';
import { logger } from 'hono/logger';
import { validator } from 'hono/validator';

const app = new Hono();

app.use('*', logger());
app.use('/api/*', cors());

app.get('/api/users', async (c) => {
  const users = await db.users.findAll();
  return c.json(users);
});

app.post('/api/users',
  validator('json', (value, c) => {
    if (!value.name || !value.email) {
      return c.json({ error: 'Invalid input' }, 400);
    }
    return value;
  }),
  async (c) => {
    const user = await db.users.create(c.req.valid('json'));
    return c.json(user, 201);
  }
);

export default app;
```

### Testing with Vitest

Configuration:
```javascript
// vitest.config.js
import { defineConfig } from 'vitest/config';

export default defineConfig({
  test: {
    globals: true,
    environment: 'node',
    coverage: {
      provider: 'v8',
      reporter: ['text', 'json', 'html'],
    },
  },
});
```

Test Example:
```javascript
// user.test.js
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { createUser, getUser } from './user.js';

describe('User Service', () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it('should create a user', async () => {
    const user = await createUser({ name: 'John', email: '[email protected]' });
    expect(user).toMatchObject({ name: 'John', email: '[email protected]' });
    expect(user.id).toBeDefined();
  });

  it('should throw on invalid email', async () => {
    await expect(createUser({ name: 'John', email: 'invalid' }))
      .rejects.toThrow('Invalid email');
  });
});
```

### ESLint 9 Flat Config

```javascript
// eslint.config.js
import js from '@eslint/js';
import globals from 'globals';

export default [
  js.configs.recommended,
  {
    languageOptions: {
      ecmaVersion: 2025,
      sourceType: 'module',
      globals: {
        ...globals.node,
        ...globals.es2025,
      },
    },
    rules: {
      'no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
      'no-console': ['warn', { allow: ['warn', 'error'] }],
      'prefer-const': 'error',
      'no-var': 'error',
    },
  },
];
```

### Biome (All-in-One)

```json
{
  "$schema": "https://biomejs.dev/schemas/1.9.0/schema.json",
  "organizeImports": { "enabled": true },
  "linter": {
    "enabled": true,
    "rules": { "recommended": true }
  },
  "formatter": {
    "enabled": true,
    "indentStyle": "space",
    "indentWidth": 2
  },
  "javascript": {
    "formatter": {
      "quoteStyle": "single",
      "semicolons": "always"
    }
  }
}
```

---

## Advanced Patterns

For comprehensive documentation including advanced async patterns, module system details, performance optimization, and production deployment configurations, see:

- [reference.md](reference.md) - Complete API reference, Context7 library mappings, package manager comparison
- [examples.md](examples.md) - Production-ready code examples, full-stack patterns, testing templates

### Context7 Integration

```javascript
// Node.js - mcp__context7__get_library_docs("/nodejs/node", "esm modules async", 1)
// Express - mcp__context7__get_library_docs("/expressjs/express", "middleware routing", 1)
// Fastify - mcp__context7__get_library_docs("/fastify/fastify", "plugins hooks", 1)
// Hono - mcp__context7__get_library_docs("/honojs/hono", "middleware validators", 1)
// Vitest - mcp__context7__get_library_docs("/vitest-dev/vitest", "mocking coverage", 1)
```

---

## Works Well With

- `moai-lang-typescript` - TypeScript integration, type checking with JSDoc
- `moai-domain-backend` - API design, microservices architecture
- `moai-domain-database` - Database integration, ORM patterns
- `moai-workflow-testing` - TDD workflows, testing strategies
- `moai-foundation-quality` - Code quality standards
- `moai-essentials-debug` - Debugging JavaScript applications

---

## Quick Troubleshooting

Module System Issues:
```bash
# Check package.json type
cat package.json | grep '"type"'

# ESM: "type": "module" - use import/export
# CommonJS: "type": "commonjs" or omitted - use require/module.exports
```

Node.js Version Check:
```bash
node --version  # Should be 20.x or 22.x LTS
npm --version   # Should be 10.x+
```

Common Fixes:
```bash
# Clear npm cache
npm cache clean --force

# Delete node_modules and reinstall
rm -rf node_modules package-lock.json && npm install

# Fix permission issues
npm config set prefix ~/.npm-global
```

ESM/CommonJS Interop:
```javascript
// Import CommonJS from ESM
import pkg from 'commonjs-package';
const { namedExport } = pkg;

// Dynamic import in CommonJS
const { default: esmModule } = await import('esm-package');
```

---

Last Updated: 2025-12-22
Status: Active (v1.0.0)


---

## Referenced Files

> The following files are referenced in this skill and included for context.

### reference.md

```markdown
# JavaScript Development Reference

## ES2024/ES2025 Complete Reference

### ES2024 Feature Matrix

| Feature | Description | Use Case |
|---------|-------------|----------|
| Set Methods | intersection, union, difference, etc. | Collection operations |
| Promise.withResolvers | External resolve/reject access | Deferred promises |
| Immutable Arrays | toSorted, toReversed, toSpliced, with | Functional programming |
| Object.groupBy | Group array items by key | Data categorization |
| Unicode String Methods | isWellFormed, toWellFormed | Unicode validation |
| ArrayBuffer Resizing | resize, transfer methods | Memory management |

### ES2025 Feature Matrix

| Feature | Description | Use Case |
|---------|-------------|----------|
| Import Attributes | with { type: 'json' } | JSON/CSS modules |
| RegExp.escape | Escape regex special chars | Safe regex patterns |
| Iterator Helpers | map, filter, take on iterators | Lazy iteration |
| Float16Array | 16-bit floating point arrays | ML/Graphics |
| Duplicate Named Capture Groups | Same name in regex alternation | Pattern matching |

### Complete Set Operations

```javascript
const setA = new Set([1, 2, 3, 4, 5]);
const setB = new Set([4, 5, 6, 7, 8]);

// Union - all elements from both sets
const union = setA.union(setB);
// Set {1, 2, 3, 4, 5, 6, 7, 8}

// Intersection - elements in both sets
const intersection = setA.intersection(setB);
// Set {4, 5}

// Difference - elements in A but not in B
const difference = setA.difference(setB);
// Set {1, 2, 3}

// Symmetric Difference - elements in either but not both
const symmetricDiff = setA.symmetricDifference(setB);
// Set {1, 2, 3, 6, 7, 8}

// Subset check - all elements of A are in B
setA.isSubsetOf(setB); // false
new Set([4, 5]).isSubsetOf(setB); // true

// Superset check - A contains all elements of B
setA.isSupersetOf(new Set([1, 2])); // true

// Disjoint check - no common elements
setA.isDisjointFrom(new Set([10, 11])); // true
```

### Iterator Helpers (ES2025)

```javascript
function* fibonacci() {
  let a = 0, b = 1;
  while (true) {
    yield a;
    [a, b] = [b, a + b];
  }
}

// Take first 10 Fibonacci numbers
const first10 = fibonacci().take(10).toArray();
// [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

// Filter and map
const evenFib = fibonacci()
  .filter(n => n % 2 === 0)
  .map(n => n * 2)
  .take(5)
  .toArray();
// [0, 4, 16, 68, 288]

// Reduce with iterator
const sum = fibonacci()
  .take(10)
  .reduce((acc, n) => acc + n, 0);
// 88

// forEach on iterator
fibonacci()
  .take(5)
  .forEach(n => console.log(n));

// Find on iterator
const firstOver100 = fibonacci().find(n => n > 100);
// 144

// Some and every
fibonacci().take(10).some(n => n > 10); // true
fibonacci().take(5).every(n => n < 10); // true
```

---

## Node.js Runtime Reference

### Node.js Version Comparison

| Feature | Node.js 20 LTS | Node.js 22 LTS |
|---------|----------------|----------------|
| ES Modules | Full support | Full support |
| Fetch API | Stable | Stable |
| WebSocket | Experimental | Stable (default) |
| Watch Mode | Experimental | Stable |
| TypeScript | Via loaders | Native (strip types) |
| Permission Model | Experimental | Stable |
| Test Runner | Stable | Enhanced |
| Startup Time | Baseline | 30% faster |

### Node.js Built-in Test Runner

```javascript
// test/user.test.js
import { test, describe, before, after, mock } from 'node:test';
import assert from 'node:assert';
import { createUser, getUser } from '../src/user.js';

describe('User Service', () => {
  let mockDb;

  before(() => {
    mockDb = mock.fn(() => ({ id: 1, name: 'Test' }));
  });

  after(() => {
    mock.reset();
  });

  test('creates user successfully', async (t) => {
    const user = await createUser({ name: 'John', email: '[email protected]' });
    assert.ok(user.id);
    assert.strictEqual(user.name, 'John');
  });

  test('throws on duplicate email', async (t) => {
    await assert.rejects(
      async () => createUser({ name: 'Jane', email: '[email protected]' }),
      { code: 'DUPLICATE_EMAIL' }
    );
  });

  test('skipped test', { skip: true }, () => {
    // This test will be skipped
  });

  test('todo test', { todo: 'implement later' }, () => {
    // This test is marked as todo
  });
});
```

Run tests:
```bash
# Run all tests
node --test

# Run specific file
node --test test/user.test.js

# With coverage
node --test --experimental-test-coverage

# Watch mode
node --test --watch

# Parallel execution
node --test --test-concurrency=4
```

### Module System Deep Dive

Package.json Configuration:
```json
{
  "name": "my-package",
  "version": "1.0.0",
  "type": "module",
  "main": "./dist/index.cjs",
  "module": "./dist/index.js",
  "exports": {
    ".": {
      "import": "./dist/index.js",
      "require": "./dist/index.cjs",
      "types": "./dist/index.d.ts"
    },
    "./utils": {
      "import": "./dist/utils.js",
      "require": "./dist/utils.cjs"
    }
  },
  "engines": {
    "node": ">=20.0.0"
  }
}
```

ESM/CommonJS Interoperability:
```javascript
// ESM importing CommonJS
import cjsModule from 'commonjs-package';
import { createRequire } from 'node:module';

const require = createRequire(import.meta.url);
const cjsPackage = require('commonjs-only-package');

// Get __dirname and __filename in ESM
import { fileURLToPath } from 'node:url';
import { dirname } from 'node:path';

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

// Dynamic import (works in both)
const module = await import('./dynamic-module.js');
```

---

## Package Manager Comparison

| Feature | npm | yarn | pnpm | bun |
|---------|-----|------|------|-----|
| Speed | Baseline | Faster | Fastest Node | Fastest overall |
| Disk Usage | High | High | Low (symlinks) | Low |
| Workspaces | Yes | Yes | Yes | Yes |
| Lockfile | package-lock.json | yarn.lock | pnpm-lock.yaml | bun.lockb |
| Plug'n'Play | No | Yes | No | No |
| Node.js Only | Yes | Yes | Yes | No (own runtime) |

### pnpm Commands

```bash
# Initialize
pnpm init

# Install dependencies
pnpm install
pnpm add express
pnpm add -D vitest

# Workspaces
pnpm -r install      # Install all workspaces
pnpm --filter=api test  # Run in specific workspace

# Performance
pnpm store prune    # Clean unused packages
pnpm dedupe        # Deduplicate dependencies
```

### Bun Commands

```bash
# Initialize
bun init

# Install (incredibly fast)
bun install
bun add express
bun add -d vitest

# Run scripts
bun run dev
bun run test

# Execute files directly
bun run server.js
bun run app.ts  # Native TypeScript support

# Built-in bundler
bun build ./src/index.ts --outdir=./dist
```

---

## Framework Reference

### Express Middleware Patterns

```javascript
import express from 'express';
import helmet from 'helmet';
import compression from 'compression';
import rateLimit from 'express-rate-limit';

const app = express();

// Security middleware
app.use(helmet());
app.use(compression());

// Rate limiting
const limiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 100, // limit each IP to 100 requests per windowMs
  standardHeaders: true,
  legacyHeaders: false,
});
app.use('/api/', limiter);

// Request logging
app.use((req, res, next) => {
  const start = Date.now();
  res.on('finish', () => {
    console.log(`${req.method} ${req.url} ${res.statusCode} ${Date.now() - start}ms`);
  });
  next();
});

// Error handling middleware
app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(err.status || 500).json({
    error: {
      message: err.message,
      ...(process.env.NODE_ENV === 'development' && { stack: err.stack }),
    },
  });
});
```

### Fastify Plugin Architecture

```javascript
import Fastify from 'fastify';
import fastifySwagger from '@fastify/swagger';
import fastifySwaggerUi from '@fastify/swagger-ui';
import fastifyCors from '@fastify/cors';

const fastify = Fastify({
  logger: {
    level: 'info',
    transport: {
      target: 'pino-pretty',
    },
  },
});

// Register plugins
await fastify.register(fastifyCors, { origin: true });

await fastify.register(fastifySwagger, {
  openapi: {
    info: {
      title: 'My API',
      version: '1.0.0',
    },
  },
});

await fastify.register(fastifySwaggerUi, {
  routePrefix: '/docs',
});

// Custom plugin
const myPlugin = async (fastify, options) => {
  fastify.decorate('db', options.database);

  fastify.addHook('onRequest', async (request) => {
    request.startTime = Date.now();
  });

  fastify.addHook('onResponse', async (request, reply) => {
    const duration = Date.now() - request.startTime;
    fastify.log.info({ duration, url: request.url }, 'request completed');
  });
};

fastify.register(myPlugin, { database: db });
```

### Hono Adapters and Middleware

```javascript
import { Hono } from 'hono';
import { serve } from '@hono/node-server';
import { cors } from 'hono/cors';
import { logger } from 'hono/logger';
import { secureHeaders } from 'hono/secure-headers';
import { jwt } from 'hono/jwt';
import { zValidator } from '@hono/zod-validator';
import { z } from 'zod';

const app = new Hono();

// Middleware stack
app.use('*', logger());
app.use('*', secureHeaders());
app.use('/api/*', cors());

// JWT authentication
app.use('/api/protected/*', jwt({ secret: process.env.JWT_SECRET }));

// Zod validation
const createUserSchema = z.object({
  name: z.string().min(2).max(100),
  email: z.string().email(),
});

app.post('/api/users',
  zValidator('json', createUserSchema),
  async (c) => {
    const data = c.req.valid('json');
    const user = await db.users.create(data);
    return c.json(user, 201);
  }
);

// Error handling
app.onError((err, c) => {
  console.error(err);
  return c.json({ error: err.message }, 500);
});

// Not found handler
app.notFound((c) => c.json({ error: 'Not found' }, 404));

// Node.js adapter
serve({ fetch: app.fetch, port: 3000 });

// Or export for Cloudflare Workers, Deno, Bun
export default app;
```

---

## Testing Reference

### Vitest vs Jest Comparison

| Feature | Vitest | Jest |
|---------|--------|------|
| Speed | 4x faster cold, instant HMR | Baseline |
| ESM Support | Native | Requires config |
| TypeScript | Native | Via ts-jest/babel |
| Configuration | vite.config.js | jest.config.js |
| Watch Mode | Instant rerun | Full rerun |
| Snapshot Testing | Yes | Yes |
| Coverage | v8/istanbul | istanbul |
| Concurrent Tests | Per-file default | Optional |

### Vitest Mocking Patterns

```javascript
import { vi, describe, it, expect, beforeEach, afterEach } from 'vitest';
import { fetchUser, createUser } from './user.js';

// Mock module
vi.mock('./database.js', () => ({
  db: {
    users: {
      findById: vi.fn(),
      create: vi.fn(),
    },
  },
}));

import { db } from './database.js';

describe('User functions', () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  afterEach(() => {
    vi.restoreAllMocks();
  });

  it('fetches user from database', async () => {
    const mockUser = { id: 1, name: 'John' };
    db.users.findById.mockResolvedValue(mockUser);

    const user = await fetchUser(1);

    expect(db.users.findById).toHaveBeenCalledWith(1);
    expect(user).toEqual(mockUser);
  });

  it('handles fetch errors', async () => {
    db.users.findById.mockRejectedValue(new Error('DB Error'));

    await expect(fetchUser(1)).rejects.toThrow('DB Error');
  });

  // Spy on existing implementation
  it('spies on console.log', () => {
    const spy = vi.spyOn(console, 'log');
    console.log('test');
    expect(spy).toHaveBeenCalledWith('test');
  });

  // Timer mocks
  it('handles timers', async () => {
    vi.useFakeTimers();

    const callback = vi.fn();
    setTimeout(callback, 1000);

    vi.advanceTimersByTime(1000);
    expect(callback).toHaveBeenCalled();

    vi.useRealTimers();
  });
});
```

---

## Build Tools Reference

### Vite Configuration

```javascript
// vite.config.js
import { defineConfig } from 'vite';
import { resolve } from 'path';

export default defineConfig({
  build: {
    target: 'es2022',
    outDir: 'dist',
    lib: {
      entry: resolve(__dirname, 'src/index.js'),
      name: 'MyLib',
      formats: ['es', 'cjs'],
      fileName: (format) => `index.${format === 'es' ? 'js' : 'cjs'}`,
    },
    rollupOptions: {
      external: ['express', 'fastify'],
      output: {
        manualChunks: {
          vendor: ['lodash-es'],
        },
      },
    },
    minify: 'esbuild',
    sourcemap: true,
  },
  esbuild: {
    target: 'es2022',
    keepNames: true,
  },
  server: {
    port: 3000,
    hmr: true,
  },
});
```

### esbuild Direct Usage

```javascript
// build.js
import * as esbuild from 'esbuild';

await esbuild.build({
  entryPoints: ['src/index.js'],
  bundle: true,
  minify: true,
  sourcemap: true,
  target: ['es2022'],
  platform: 'node',
  format: 'esm',
  outdir: 'dist',
  external: ['express', 'pg'],
  define: {
    'process.env.NODE_ENV': '"production"',
  },
});

// Watch mode
const ctx = await esbuild.context({
  entryPoints: ['src/index.js'],
  bundle: true,
  outdir: 'dist',
});

await ctx.watch();
console.log('watching...');
```

---

## Context7 Library Mappings

### Primary Libraries

```
/nodejs/node           - Node.js runtime
/expressjs/express     - Express web framework
/fastify/fastify       - Fastify web framework
/honojs/hono           - Hono web framework
/koajs/koa             - Koa web framework
```

### Testing

```
/vitest-dev/vitest     - Vitest testing framework
/jestjs/jest           - Jest testing framework
/testing-library       - Testing Library
```

### Build Tools

```
/vitejs/vite           - Vite build tool
/evanw/esbuild         - esbuild bundler
/rollup/rollup         - Rollup bundler
/biomejs/biome         - Biome linter/formatter
/eslint/eslint         - ESLint linter
```

### Utilities

```
/lodash/lodash         - Lodash utilities
/date-fns/date-fns     - Date utilities
/axios/axios           - HTTP client
/prisma/prisma         - Prisma ORM
```

---

## Security Best Practices

### Input Validation

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

const userSchema = z.object({
  name: z.string().min(1).max(100).trim(),
  email: z.string().email().toLowerCase(),
  age: z.number().int().min(0).max(150).optional(),
});

function validateUser(input) {
  const result = userSchema.safeParse(input);
  if (!result.success) {
    throw new Error(result.error.issues[0].message);
  }
  return result.data;
}
```

### Environment Variable Validation

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

const envSchema = z.object({
  NODE_ENV: z.enum(['development', 'production', 'test']),
  PORT: z.string().transform(Number).pipe(z.number().min(1).max(65535)),
  DATABASE_URL: z.string().url(),
  JWT_SECRET: z.string().min(32),
});

const env = envSchema.parse(process.env);
export default env;
```

### Secure HTTP Headers

```javascript
import helmet from 'helmet';

app.use(helmet({
  contentSecurityPolicy: {
    directives: {
      defaultSrc: ["'self'"],
      scriptSrc: ["'self'"],
      styleSrc: ["'self'", "'unsafe-inline'"],
      imgSrc: ["'self'", "data:", "https:"],
    },
  },
  crossOriginEmbedderPolicy: true,
  crossOriginOpenerPolicy: true,
  crossOriginResourcePolicy: { policy: "same-origin" },
  hsts: { maxAge: 31536000, includeSubDomains: true },
}));
```

---

Last Updated: 2025-12-22
Version: 1.0.0

```

### examples.md

```markdown
# JavaScript Production-Ready Examples

## Full-Stack Application Setup

### Project Structure

```
my-api/
├── src/
│   ├── index.js              # Application entry point
│   ├── config/
│   │   ├── index.js          # Configuration loader
│   │   └── database.js       # Database configuration
│   ├── api/
│   │   ├── routes/
│   │   │   ├── index.js      # Route aggregator
│   │   │   ├── users.js      # User routes
│   │   │   └── posts.js      # Post routes
│   │   └── middleware/
│   │       ├── auth.js       # Authentication
│   │       ├── validate.js   # Request validation
│   │       └── errorHandler.js
│   ├── services/
│   │   ├── userService.js    # Business logic
│   │   └── postService.js
│   ├── repositories/
│   │   ├── userRepository.js # Data access
│   │   └── postRepository.js
│   └── utils/
│       ├── logger.js
│       └── helpers.js
├── test/
│   ├── unit/
│   ├── integration/
│   └── fixtures/
├── package.json
├── eslint.config.js
├── vitest.config.js
└── Dockerfile
```

### package.json

```json
{
  "name": "my-api",
  "version": "1.0.0",
  "type": "module",
  "engines": {
    "node": ">=22.0.0"
  },
  "scripts": {
    "dev": "node --watch src/index.js",
    "start": "node src/index.js",
    "test": "vitest",
    "test:coverage": "vitest run --coverage",
    "test:e2e": "vitest run --config vitest.e2e.config.js",
    "lint": "eslint src/",
    "lint:fix": "eslint src/ --fix",
    "format": "biome format --write src/",
    "check": "biome check src/",
    "typecheck": "tsc --noEmit"
  },
  "dependencies": {
    "fastify": "^5.0.0",
    "@fastify/cors": "^10.0.0",
    "@fastify/helmet": "^12.0.0",
    "@fastify/rate-limit": "^10.0.0",
    "@fastify/swagger": "^9.0.0",
    "@fastify/swagger-ui": "^5.0.0",
    "zod": "^3.23.0",
    "pg": "^8.13.0",
    "pino": "^9.5.0",
    "pino-pretty": "^13.0.0",
    "dotenv": "^16.4.0"
  },
  "devDependencies": {
    "@biomejs/biome": "^1.9.0",
    "eslint": "^9.15.0",
    "@eslint/js": "^9.15.0",
    "globals": "^15.12.0",
    "vitest": "^2.1.0",
    "@vitest/coverage-v8": "^2.1.0",
    "typescript": "^5.7.0",
    "@types/node": "^22.10.0"
  }
}
```

---

## Fastify Complete API Example

### src/index.js

```javascript
import Fastify from 'fastify';
import cors from '@fastify/cors';
import helmet from '@fastify/helmet';
import rateLimit from '@fastify/rate-limit';
import swagger from '@fastify/swagger';
import swaggerUi from '@fastify/swagger-ui';
import { config } from './config/index.js';
import { routes } from './api/routes/index.js';
import { errorHandler } from './api/middleware/errorHandler.js';
import { logger } from './utils/logger.js';

const app = Fastify({
  logger: logger,
  disableRequestLogging: false,
});

// Security plugins
await app.register(helmet);
await app.register(cors, {
  origin: config.corsOrigins,
  credentials: true,
});
await app.register(rateLimit, {
  max: 100,
  timeWindow: '1 minute',
});

// API documentation
await app.register(swagger, {
  openapi: {
    info: {
      title: 'My API',
      description: 'API documentation',
      version: '1.0.0',
    },
    servers: [{ url: config.apiUrl }],
    components: {
      securitySchemes: {
        bearerAuth: {
          type: 'http',
          scheme: 'bearer',
          bearerFormat: 'JWT',
        },
      },
    },
  },
});
await app.register(swaggerUi, { routePrefix: '/docs' });

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

// Error handling
app.setErrorHandler(errorHandler);

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

// Start server
const start = async () => {
  try {
    await app.listen({ port: config.port, host: '0.0.0.0' });
    app.log.info(`Server running on http://localhost:${config.port}`);
  } catch (err) {
    app.log.error(err);
    process.exit(1);
  }
};

start();

export { app };
```

### src/config/index.js

```javascript
import { z } from 'zod';
import 'dotenv/config';

const envSchema = z.object({
  NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),
  PORT: z.string().transform(Number).default('3000'),
  DATABASE_URL: z.string().url(),
  JWT_SECRET: z.string().min(32),
  CORS_ORIGINS: z.string().default('http://localhost:3000'),
  API_URL: z.string().url().default('http://localhost:3000'),
  LOG_LEVEL: z.enum(['debug', 'info', 'warn', 'error']).default('info'),
});

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 config = {
  nodeEnv: parsed.data.NODE_ENV,
  port: parsed.data.PORT,
  databaseUrl: parsed.data.DATABASE_URL,
  jwtSecret: parsed.data.JWT_SECRET,
  corsOrigins: parsed.data.CORS_ORIGINS.split(','),
  apiUrl: parsed.data.API_URL,
  logLevel: parsed.data.LOG_LEVEL,
  isDev: parsed.data.NODE_ENV === 'development',
  isProd: parsed.data.NODE_ENV === 'production',
};
```

### src/api/routes/users.js

```javascript
import { z } from 'zod';
import { userService } from '../../services/userService.js';
import { authenticate } from '../middleware/auth.js';

const createUserSchema = z.object({
  name: z.string().min(2).max(100),
  email: z.string().email(),
  password: z.string().min(8).max(100),
});

const updateUserSchema = z.object({
  name: z.string().min(2).max(100).optional(),
  email: z.string().email().optional(),
});

const idParamSchema = z.object({
  id: z.string().uuid(),
});

const querySchema = z.object({
  page: z.string().transform(Number).default('1'),
  limit: z.string().transform(Number).default('10'),
  search: z.string().optional(),
});

export async function userRoutes(fastify) {
  // List users
  fastify.get('/', {
    schema: {
      tags: ['Users'],
      querystring: querySchema,
      response: {
        200: {
          type: 'object',
          properties: {
            users: { type: 'array' },
            pagination: { type: 'object' },
          },
        },
      },
    },
    handler: async (request, reply) => {
      const query = querySchema.parse(request.query);
      const result = await userService.list(query);
      return result;
    },
  });

  // Get user by ID
  fastify.get('/:id', {
    schema: {
      tags: ['Users'],
      params: idParamSchema,
    },
    handler: async (request, reply) => {
      const { id } = idParamSchema.parse(request.params);
      const user = await userService.getById(id);
      if (!user) {
        return reply.code(404).send({ error: 'User not found' });
      }
      return user;
    },
  });

  // Create user
  fastify.post('/', {
    schema: {
      tags: ['Users'],
      body: createUserSchema,
    },
    handler: async (request, reply) => {
      const data = createUserSchema.parse(request.body);
      const user = await userService.create(data);
      return reply.code(201).send(user);
    },
  });

  // Update user (protected)
  fastify.put('/:id', {
    preHandler: [authenticate],
    schema: {
      tags: ['Users'],
      security: [{ bearerAuth: [] }],
      params: idParamSchema,
      body: updateUserSchema,
    },
    handler: async (request, reply) => {
      const { id } = idParamSchema.parse(request.params);
      const data = updateUserSchema.parse(request.body);
      const user = await userService.update(id, data);
      return user;
    },
  });

  // Delete user (protected)
  fastify.delete('/:id', {
    preHandler: [authenticate],
    schema: {
      tags: ['Users'],
      security: [{ bearerAuth: [] }],
      params: idParamSchema,
    },
    handler: async (request, reply) => {
      const { id } = idParamSchema.parse(request.params);
      await userService.delete(id);
      return reply.code(204).send();
    },
  });
}
```

### src/services/userService.js

```javascript
import { userRepository } from '../repositories/userRepository.js';
import { hashPassword, verifyPassword } from '../utils/crypto.js';

class UserService {
  async list({ page, limit, search }) {
    const offset = (page - 1) * limit;
    const [users, total] = await Promise.all([
      userRepository.findMany({ offset, limit, search }),
      userRepository.count({ search }),
    ]);

    return {
      users,
      pagination: {
        page,
        limit,
        total,
        totalPages: Math.ceil(total / limit),
      },
    };
  }

  async getById(id) {
    return userRepository.findById(id);
  }

  async create(data) {
    // Check for existing email
    const existing = await userRepository.findByEmail(data.email);
    if (existing) {
      throw new Error('Email already exists');
    }

    // Hash password
    const hashedPassword = await hashPassword(data.password);

    return userRepository.create({
      ...data,
      password: hashedPassword,
    });
  }

  async update(id, data) {
    const user = await userRepository.findById(id);
    if (!user) {
      throw new Error('User not found');
    }

    if (data.email && data.email !== user.email) {
      const existing = await userRepository.findByEmail(data.email);
      if (existing) {
        throw new Error('Email already exists');
      }
    }

    return userRepository.update(id, data);
  }

  async delete(id) {
    const user = await userRepository.findById(id);
    if (!user) {
      throw new Error('User not found');
    }
    return userRepository.delete(id);
  }

  async authenticate(email, password) {
    const user = await userRepository.findByEmail(email);
    if (!user) {
      return null;
    }

    const valid = await verifyPassword(password, user.password);
    if (!valid) {
      return null;
    }

    return user;
  }
}

export const userService = new UserService();
```

### src/repositories/userRepository.js

```javascript
import { db } from '../config/database.js';

class UserRepository {
  async findMany({ offset, limit, search }) {
    let query = `
      SELECT id, name, email, created_at, updated_at
      FROM users
    `;
    const params = [];

    if (search) {
      query += ` WHERE name ILIKE $1 OR email ILIKE $1`;
      params.push(`%${search}%`);
    }

    query += ` ORDER BY created_at DESC LIMIT $${params.length + 1} OFFSET $${params.length + 2}`;
    params.push(limit, offset);

    const result = await db.query(query, params);
    return result.rows;
  }

  async count({ search }) {
    let query = `SELECT COUNT(*) FROM users`;
    const params = [];

    if (search) {
      query += ` WHERE name ILIKE $1 OR email ILIKE $1`;
      params.push(`%${search}%`);
    }

    const result = await db.query(query, params);
    return parseInt(result.rows[0].count);
  }

  async findById(id) {
    const result = await db.query(
      `SELECT id, name, email, created_at, updated_at FROM users WHERE id = $1`,
      [id]
    );
    return result.rows[0] || null;
  }

  async findByEmail(email) {
    const result = await db.query(
      `SELECT id, name, email, password, created_at, updated_at FROM users WHERE email = $1`,
      [email]
    );
    return result.rows[0] || null;
  }

  async create(data) {
    const result = await db.query(
      `INSERT INTO users (name, email, password)
       VALUES ($1, $2, $3)
       RETURNING id, name, email, created_at, updated_at`,
      [data.name, data.email, data.password]
    );
    return result.rows[0];
  }

  async update(id, data) {
    const fields = [];
    const values = [];
    let paramIndex = 1;

    for (const [key, value] of Object.entries(data)) {
      if (value !== undefined) {
        fields.push(`${key} = $${paramIndex}`);
        values.push(value);
        paramIndex++;
      }
    }

    if (fields.length === 0) {
      return this.findById(id);
    }

    fields.push(`updated_at = NOW()`);
    values.push(id);

    const result = await db.query(
      `UPDATE users SET ${fields.join(', ')} WHERE id = $${paramIndex}
       RETURNING id, name, email, created_at, updated_at`,
      values
    );
    return result.rows[0];
  }

  async delete(id) {
    await db.query(`DELETE FROM users WHERE id = $1`, [id]);
  }
}

export const userRepository = new UserRepository();
```

---

## Testing Examples

### vitest.config.js

```javascript
import { defineConfig } from 'vitest/config';

export default defineConfig({
  test: {
    globals: true,
    environment: 'node',
    include: ['test/**/*.test.js'],
    coverage: {
      provider: 'v8',
      reporter: ['text', 'json', 'html'],
      include: ['src/**/*.js'],
      exclude: ['src/index.js'],
      thresholds: {
        lines: 80,
        functions: 80,
        branches: 75,
        statements: 80,
      },
    },
    setupFiles: ['test/setup.js'],
  },
});
```

### test/setup.js

```javascript
import { beforeAll, afterAll, afterEach, vi } from 'vitest';

// Mock environment variables
process.env.NODE_ENV = 'test';
process.env.DATABASE_URL = 'postgres://test:test@localhost:5432/test';
process.env.JWT_SECRET = 'test-secret-key-at-least-32-characters';
process.env.PORT = '3001';

// Global test setup
beforeAll(async () => {
  // Setup test database, start test server, etc.
});

afterAll(async () => {
  // Cleanup
});

afterEach(() => {
  vi.clearAllMocks();
});
```

### test/unit/userService.test.js

```javascript
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { userService } from '../../src/services/userService.js';
import { userRepository } from '../../src/repositories/userRepository.js';

// Mock repository
vi.mock('../../src/repositories/userRepository.js', () => ({
  userRepository: {
    findMany: vi.fn(),
    count: vi.fn(),
    findById: vi.fn(),
    findByEmail: vi.fn(),
    create: vi.fn(),
    update: vi.fn(),
    delete: vi.fn(),
  },
}));

// Mock crypto utilities
vi.mock('../../src/utils/crypto.js', () => ({
  hashPassword: vi.fn((p) => `hashed_${p}`),
  verifyPassword: vi.fn((plain, hashed) => hashed === `hashed_${plain}`),
}));

describe('UserService', () => {
  const mockUser = {
    id: '123e4567-e89b-12d3-a456-426614174000',
    name: 'John Doe',
    email: '[email protected]',
    created_at: new Date(),
    updated_at: new Date(),
  };

  beforeEach(() => {
    vi.clearAllMocks();
  });

  describe('list', () => {
    it('returns paginated users', async () => {
      userRepository.findMany.mockResolvedValue([mockUser]);
      userRepository.count.mockResolvedValue(1);

      const result = await userService.list({ page: 1, limit: 10 });

      expect(result.users).toHaveLength(1);
      expect(result.pagination).toEqual({
        page: 1,
        limit: 10,
        total: 1,
        totalPages: 1,
      });
    });

    it('calculates offset correctly', async () => {
      userRepository.findMany.mockResolvedValue([]);
      userRepository.count.mockResolvedValue(0);

      await userService.list({ page: 3, limit: 20 });

      expect(userRepository.findMany).toHaveBeenCalledWith({
        offset: 40,
        limit: 20,
        search: undefined,
      });
    });
  });

  describe('create', () => {
    it('creates user with hashed password', async () => {
      userRepository.findByEmail.mockResolvedValue(null);
      userRepository.create.mockResolvedValue(mockUser);

      const result = await userService.create({
        name: 'John Doe',
        email: '[email protected]',
        password: 'password123',
      });

      expect(userRepository.create).toHaveBeenCalledWith({
        name: 'John Doe',
        email: '[email protected]',
        password: 'hashed_password123',
      });
      expect(result).toEqual(mockUser);
    });

    it('throws on duplicate email', async () => {
      userRepository.findByEmail.mockResolvedValue(mockUser);

      await expect(
        userService.create({
          name: 'Jane',
          email: '[email protected]',
          password: 'password',
        })
      ).rejects.toThrow('Email already exists');
    });
  });

  describe('authenticate', () => {
    it('returns user on valid credentials', async () => {
      const userWithPassword = { ...mockUser, password: 'hashed_password123' };
      userRepository.findByEmail.mockResolvedValue(userWithPassword);

      const result = await userService.authenticate('[email protected]', 'password123');

      expect(result).toEqual(userWithPassword);
    });

    it('returns null on invalid password', async () => {
      const userWithPassword = { ...mockUser, password: 'hashed_password123' };
      userRepository.findByEmail.mockResolvedValue(userWithPassword);

      const result = await userService.authenticate('[email protected]', 'wrongpassword');

      expect(result).toBeNull();
    });

    it('returns null on non-existent user', async () => {
      userRepository.findByEmail.mockResolvedValue(null);

      const result = await userService.authenticate('[email protected]', 'password');

      expect(result).toBeNull();
    });
  });
});
```

### test/integration/users.test.js

```javascript
import { describe, it, expect, beforeAll, afterAll, beforeEach } from 'vitest';
import { app } from '../../src/index.js';
import { db } from '../../src/config/database.js';

describe('Users API', () => {
  beforeAll(async () => {
    await app.ready();
  });

  afterAll(async () => {
    await app.close();
    await db.end();
  });

  beforeEach(async () => {
    // Clean up database
    await db.query('DELETE FROM users');
  });

  describe('POST /api/v1/users', () => {
    it('creates a new user', async () => {
      const response = await app.inject({
        method: 'POST',
        url: '/api/v1/users',
        payload: {
          name: 'John Doe',
          email: '[email protected]',
          password: 'password123',
        },
      });

      expect(response.statusCode).toBe(201);
      const body = JSON.parse(response.body);
      expect(body).toMatchObject({
        name: 'John Doe',
        email: '[email protected]',
      });
      expect(body.id).toBeDefined();
      expect(body.password).toBeUndefined();
    });

    it('returns 400 for invalid email', async () => {
      const response = await app.inject({
        method: 'POST',
        url: '/api/v1/users',
        payload: {
          name: 'John Doe',
          email: 'invalid-email',
          password: 'password123',
        },
      });

      expect(response.statusCode).toBe(400);
    });
  });

  describe('GET /api/v1/users', () => {
    it('returns paginated users', async () => {
      // Create test users
      await db.query(
        `INSERT INTO users (name, email, password) VALUES
         ('User 1', '[email protected]', 'hashed'),
         ('User 2', '[email protected]', 'hashed')`
      );

      const response = await app.inject({
        method: 'GET',
        url: '/api/v1/users?page=1&limit=10',
      });

      expect(response.statusCode).toBe(200);
      const body = JSON.parse(response.body);
      expect(body.users).toHaveLength(2);
      expect(body.pagination.total).toBe(2);
    });
  });
});
```

---

## Hono Edge Example

### src/index.js (Edge/Serverless)

```javascript
import { Hono } from 'hono';
import { cors } from 'hono/cors';
import { logger } from 'hono/logger';
import { secureHeaders } from 'hono/secure-headers';
import { prettyJSON } from 'hono/pretty-json';
import { compress } from 'hono/compress';
import { cache } from 'hono/cache';
import { jwt } from 'hono/jwt';
import { zValidator } from '@hono/zod-validator';
import { z } from 'zod';

const app = new Hono();

// Middleware
app.use('*', logger());
app.use('*', secureHeaders());
app.use('*', compress());
app.use('/api/*', cors());
app.use('/api/*', prettyJSON());

// Cache static responses
app.get('/api/health', cache({ cacheName: 'health', cacheControl: 'max-age=60' }));

// Health check
app.get('/api/health', (c) => c.json({ status: 'ok', timestamp: Date.now() }));

// JWT protected routes
app.use('/api/protected/*', jwt({ secret: Bun.env.JWT_SECRET }));

// Validation schemas
const createPostSchema = z.object({
  title: z.string().min(1).max(200),
  content: z.string().min(1),
  tags: z.array(z.string()).optional(),
});

// Routes with validation
app.post('/api/posts',
  jwt({ secret: Bun.env.JWT_SECRET }),
  zValidator('json', createPostSchema),
  async (c) => {
    const payload = c.get('jwtPayload');
    const data = c.req.valid('json');

    // Create post logic
    const post = {
      id: crypto.randomUUID(),
      ...data,
      authorId: payload.sub,
      createdAt: new Date().toISOString(),
    };

    return c.json(post, 201);
  }
);

app.get('/api/posts', async (c) => {
  const page = Number(c.req.query('page') || '1');
  const limit = Number(c.req.query('limit') || '10');

  // Fetch posts logic
  return c.json({
    posts: [],
    pagination: { page, limit, total: 0 },
  });
});

// Error handling
app.onError((err, c) => {
  console.error(`${err}`);
  return c.json({ error: err.message }, 500);
});

app.notFound((c) => c.json({ error: 'Not Found' }, 404));

// Export for different runtimes
export default app;

// Bun
// Bun.serve({ port: 3000, fetch: app.fetch });

// Node.js
// import { serve } from '@hono/node-server';
// serve({ fetch: app.fetch, port: 3000 });
```

---

## ESLint 9 Flat Config

### eslint.config.js

```javascript
import js from '@eslint/js';
import globals from 'globals';

export default [
  {
    ignores: ['dist/', 'node_modules/', 'coverage/'],
  },
  js.configs.recommended,
  {
    files: ['**/*.js'],
    languageOptions: {
      ecmaVersion: 2025,
      sourceType: 'module',
      globals: {
        ...globals.node,
        ...globals.es2025,
      },
    },
    rules: {
      // Best practices
      'no-unused-vars': ['error', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }],
      'no-console': ['warn', { allow: ['warn', 'error', 'info'] }],
      'prefer-const': 'error',
      'no-var': 'error',
      'object-shorthand': 'error',
      'prefer-template': 'error',
      'prefer-arrow-callback': 'error',

      // Code style
      'arrow-body-style': ['error', 'as-needed'],
      'no-multiple-empty-lines': ['error', { max: 1 }],
      'eol-last': ['error', 'always'],

      // Error prevention
      'no-return-await': 'error',
      'require-await': 'error',
      'no-async-promise-executor': 'error',
      'no-promise-executor-return': 'error',
    },
  },
  {
    files: ['test/**/*.js'],
    languageOptions: {
      globals: {
        ...globals.vitest,
      },
    },
    rules: {
      'no-unused-expressions': 'off',
    },
  },
];
```

---

## Dockerfile

```dockerfile
# Build stage
FROM node:22-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production

# Production stage
FROM node:22-alpine
WORKDIR /app

# Security: run as non-root user
RUN addgroup -g 1001 -S nodejs && \
    adduser -S nodejs -u 1001

COPY --from=builder /app/node_modules ./node_modules
COPY . .

# Set ownership
RUN chown -R nodejs:nodejs /app

USER nodejs

ENV NODE_ENV=production
ENV PORT=3000

EXPOSE 3000

HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1

CMD ["node", "src/index.js"]
```

---

Last Updated: 2025-12-22
Version: 1.0.0

```

moai-lang-javascript | SkillHub