javascript-coding-standards
JavaScript/ES6+ coding standards following Airbnb guidelines, modern patterns, React best practices, and comprehensive Jest testing. Use for JavaScript projects requiring clean, maintainable, production-ready code with modern tooling.
Best use case
javascript-coding-standards is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
JavaScript/ES6+ coding standards following Airbnb guidelines, modern patterns, React best practices, and comprehensive Jest testing. Use for JavaScript projects requiring clean, maintainable, production-ready code with modern tooling.
Teams using javascript-coding-standards should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/javascript/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How javascript-coding-standards Compares
| Feature / Agent | javascript-coding-standards | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
JavaScript/ES6+ coding standards following Airbnb guidelines, modern patterns, React best practices, and comprehensive Jest testing. Use for JavaScript projects requiring clean, maintainable, production-ready code with modern tooling.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
Related Guides
SKILL.md Source
# JavaScript Coding Standards
> **Quick Navigation:**
> Level 1: [Quick Start](#level-1-quick-start-2000-tokens-5-minutes) (5 min) → Level 2: [Implementation](#level-2-implementation-5000-tokens-30-minutes) (30 min) → Level 3: [Mastery](#level-3-mastery-resources) (Extended)
---
## Level 1: Quick Start (<2,000 tokens, 5 minutes)
### Core Principles
1. **Modern JavaScript**: Use ES6+ features (arrow functions, destructuring, async/await)
2. **Type Safety**: Use TypeScript or JSDoc for type annotations where complexity warrants
3. **Test-First**: Write Jest tests before implementation
4. **Clean Code**: Follow Airbnb style guide, use meaningful names
5. **Modern Tooling**: ESLint + Prettier for consistent formatting
### Essential Checklist
- [ ] **ESLint + Prettier**: Code formatted and linted automatically
- [ ] **Modern Syntax**: Arrow functions, const/let (no var), template literals
- [ ] **Testing**: Jest tests with >80% coverage
- [ ] **Documentation**: JSDoc for complex functions and public APIs
- [ ] **Error Handling**: Try/catch for async operations, proper error types
- [ ] **Security**: Input validation, no eval(), sanitize user input
- [ ] **Module System**: ES6 modules (import/export), not CommonJS
- [ ] **Dependencies**: package.json with exact versions, npm audit passing
### Quick Example
```javascript
/**
* User authentication module with secure session handling.
* @module auth
*/
import bcrypt from 'bcrypt';
import jwt from 'jsonwebtoken';
/**
* Authenticate user with username and password.
*
* @param {string} username - User's username
* @param {string} password - Plain text password
* @returns {Promise<{success: boolean, token?: string, error?: string}>}
* @throws {ValidationError} If credentials are invalid
*
* @example
* const result = await authenticateUser('alice', 'secret123');
* if (result.success) {
* console.log('Token:', result.token);
* }
*/
export const authenticateUser = async (username, password) => {
// Validate inputs
if (!username || !password) {
throw new ValidationError('Username and password required');
}
try {
// Fetch user from database
const user = await fetchUserFromDb(username);
if (!user) {
return { success: false, error: 'Invalid credentials' };
}
// Verify password
const isValid = await bcrypt.compare(password, user.passwordHash);
if (!isValid) {
return { success: false, error: 'Invalid credentials' };
}
// Generate JWT token
const token = jwt.sign(
{ userId: user.id, username: user.username },
process.env.JWT_SECRET,
{ expiresIn: '1h' }
);
return { success: true, token };
} catch (error) {
console.error('Authentication error:', error);
throw new AuthenticationError('Authentication failed', error);
}
};
/**
* Custom validation error.
*/
class ValidationError extends Error {
constructor(message) {
super(message);
this.name = 'ValidationError';
}
}
/**
* Custom authentication error.
*/
class AuthenticationError extends Error {
constructor(message, cause) {
super(message);
this.name = 'AuthenticationError';
this.cause = cause;
}
}
```
### Quick Links to Level 2
- [Code Style & Formatting](#code-style--formatting)
- [Modern JavaScript Features](#modern-javascript-features)
- [Testing Standards](#testing-standards)
- [React Best Practices](#react-best-practices)
- [Error Handling](#error-handling)
- [Async Patterns](#async-patterns)
- [Security Considerations](#security-considerations)
---
## Level 2: Implementation (<5,000 tokens, 30 minutes)
### Code Style & Formatting
**Airbnb Style Guide + Automation**
```javascript
// ✅ Good: Modern ES6+ syntax
const calculateDiscount = (user, purchaseAmount, promoCode = null) => {
const baseDiscount = getLoyaltyDiscount(user);
const promoDiscount = promoCode ? validatePromoCode(promoCode) : 0;
return Math.min(baseDiscount + promoDiscount, 0.5);
};
// ❌ Bad: Old-style function, var, no default param
function calculateDiscount(user, purchaseAmount, promoCode) {
var baseDiscount = getLoyaltyDiscount(user);
var promoDiscount = promoCode ? validatePromoCode(promoCode) : 0;
return Math.min(baseDiscount + promoDiscount, 0.5);
}
```
**Tool Configuration** (see [resources/configs/.eslintrc.json](resources/configs/.eslintrc.json)):
```json
{
"extends": ["airbnb-base", "prettier"],
"env": {
"node": true,
"es2022": true,
"jest": true
},
"parserOptions": {
"ecmaVersion": 2022,
"sourceType": "module"
},
"rules": {
"no-console": ["warn", { "allow": ["warn", "error"] }],
"no-unused-vars": ["error", { "argsIgnorePattern": "^_" }],
"prefer-const": "error",
"no-var": "error",
"arrow-body-style": ["error", "as-needed"]
}
}
```
**Common Patterns:**
```javascript
// Destructuring
const { name, email } = user;
const [first, ...rest] = items;
// Spread operator
const newUser = { ...user, updatedAt: Date.now() };
const combined = [...array1, ...array2];
// Template literals
const message = `Welcome, ${user.name}!`;
const multiline = `
Line 1
Line 2
`;
// Optional chaining
const city = user?.address?.city;
// Nullish coalescing
const displayName = user.name ?? 'Guest';
// Object shorthand
const createUser = (name, email) => ({ name, email });
```
**Anti-Patterns:**
```javascript
// ❌ Mutating arrays (use immutable methods)
const items = [1, 2, 3];
items.push(4); // Mutation!
// ✅ Immutable approach
const newItems = [...items, 4];
// ❌ Using == instead of ===
if (value == '42') { }
// ✅ Strict equality
if (value === '42') { }
// ❌ Not handling promise rejections
fetch('/api/data'); // Unhandled promise
// ✅ Proper error handling
fetch('/api/data')
.then(response => response.json())
.catch(error => console.error('Fetch failed:', error));
```
**See Also:** [Advanced Patterns](resources/advanced-patterns.md) for generators, proxies, decorators
### Modern JavaScript Features
**ES6+ Features:**
```javascript
// Classes with private fields
class UserService {
#apiKey; // Private field
constructor(apiKey) {
this.#apiKey = apiKey;
}
async fetchUser(userId) {
const response = await fetch(`/api/users/${userId}`, {
headers: { 'X-API-Key': this.#apiKey }
});
return response.json();
}
}
// Async/Await with error handling
const processData = async (data) => {
try {
const validated = await validateData(data);
const transformed = await transformData(validated);
return await saveData(transformed);
} catch (error) {
console.error('Processing failed:', error);
throw new ProcessingError('Data processing failed', error);
}
};
// Promises with Promise.all/allSettled
const fetchAllUsers = async (userIds) => {
const promises = userIds.map(id => fetchUser(id));
// Fail fast if any request fails
const users = await Promise.all(promises);
// Or continue even if some fail
const results = await Promise.allSettled(promises);
return results
.filter(r => r.status === 'fulfilled')
.map(r => r.value);
};
// Generators for lazy evaluation
function* fibonacci() {
let [a, b] = [0, 1];
while (true) {
yield a;
[a, b] = [b, a + b];
}
}
// Symbols for unique keys
const SECRET_KEY = Symbol('secretKey');
const user = {
name: 'Alice',
[SECRET_KEY]: 'hidden value'
};
```
### Testing Standards
**Jest Best Practices:**
```javascript
// users.test.js
/**
* Tests for user service module.
*/
import { describe, test, expect, beforeEach, jest } from '@jest/globals';
import { authenticateUser } from './users.js';
import * as db from './database.js';
// Mock database module
jest.mock('./database.js');
describe('authenticateUser', () => {
beforeEach(() => {
jest.clearAllMocks();
});
test('should authenticate valid credentials', async () => {
// Arrange
const mockUser = {
id: 1,
username: 'testuser',
passwordHash: '$2b$10$...' // bcrypt hash
};
db.fetchUserFromDb.mockResolvedValue(mockUser);
// Act
const result = await authenticateUser('testuser', 'correct_password');
// Assert
expect(result.success).toBe(true);
expect(result.token).toBeDefined();
expect(db.fetchUserFromDb).toHaveBeenCalledWith('testuser');
});
test('should reject invalid password', async () => {
// Arrange
const mockUser = {
id: 1,
username: 'testuser',
passwordHash: '$2b$10$...'
};
db.fetchUserFromDb.mockResolvedValue(mockUser);
// Act
const result = await authenticateUser('testuser', 'wrong_password');
// Assert
expect(result.success).toBe(false);
expect(result.error).toBe('Invalid credentials');
expect(result.token).toBeUndefined();
});
test('should throw error for empty credentials', async () => {
// Assert
await expect(authenticateUser('', 'password'))
.rejects
.toThrow('Username and password required');
});
test.each([
['user1', 'pass1', true],
['user2', 'wrong', false],
['', 'pass', false],
])('should handle %s with %s', async (username, password, expected) => {
const result = await authenticateUser(username, password);
expect(result.success).toBe(expected);
});
});
```
**Test Organization:**
```
tests/
├── unit/ # Unit tests (fast, isolated)
│ ├── utils.test.js
│ └── models.test.js
├── integration/ # Integration tests (DB, API)
│ ├── api.test.js
│ └── database.test.js
└── e2e/ # End-to-end tests (full flow)
└── user-flows.test.js
```
**Coverage Configuration:**
```json
// jest.config.json
{
"coverageThreshold": {
"global": {
"branches": 80,
"functions": 80,
"lines": 80,
"statements": 80
}
},
"collectCoverageFrom": [
"src/**/*.js",
"!src/**/*.test.js",
"!src/**/index.js"
]
}
```
**See Also:** [Test Template](templates/test-template.js)
### React Best Practices
**Modern React Patterns:**
```javascript
// Functional components with hooks
import React, { useState, useEffect, useCallback, useMemo } from 'react';
/**
* User profile component with data fetching.
* @param {Object} props
* @param {string} props.userId - User ID to display
*/
export const UserProfile = ({ userId }) => {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
// Memoized fetch function
const fetchUser = useCallback(async () => {
try {
setLoading(true);
const response = await fetch(`/api/users/${userId}`);
if (!response.ok) throw new Error('Failed to fetch user');
const data = await response.json();
setUser(data);
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
}, [userId]);
// Effect for data fetching
useEffect(() => {
fetchUser();
}, [fetchUser]);
// Memoized computed value
const displayName = useMemo(() => {
return user ? `${user.firstName} ${user.lastName}` : 'Unknown';
}, [user]);
if (loading) return <LoadingSpinner />;
if (error) return <ErrorMessage message={error} />;
if (!user) return null;
return (
<div className="user-profile">
<h2>{displayName}</h2>
<p>{user.email}</p>
</div>
);
};
// Custom hooks for reusable logic
export const useUser = (userId) => {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
let cancelled = false;
const fetchUser = async () => {
try {
const response = await fetch(`/api/users/${userId}`);
const data = await response.json();
if (!cancelled) {
setUser(data);
setLoading(false);
}
} catch (error) {
if (!cancelled) {
setLoading(false);
}
}
};
fetchUser();
return () => {
cancelled = true; // Cleanup
};
}, [userId]);
return { user, loading };
};
```
### Error Handling
**Error Classes and Patterns:**
```javascript
// Custom error hierarchy
class AppError extends Error {
constructor(message, code, details = {}) {
super(message);
this.name = 'AppError';
this.code = code;
this.details = details;
this.timestamp = new Date().toISOString();
}
}
class ValidationError extends AppError {
constructor(field, message) {
super(
`Validation failed for ${field}: ${message}`,
'VALIDATION_ERROR',
{ field }
);
this.name = 'ValidationError';
}
}
class AuthenticationError extends AppError {
constructor(reason = 'Invalid credentials') {
super(reason, 'AUTH_ERROR', {
timestamp: Date.now()
});
this.name = 'AuthenticationError';
}
}
// Error handling middleware (Express)
export const errorHandler = (err, req, res, next) => {
// Log error
console.error('Error:', {
message: err.message,
code: err.code,
stack: err.stack,
timestamp: new Date().toISOString()
});
// Send appropriate response
if (err instanceof ValidationError) {
return res.status(400).json({
error: 'Validation Error',
message: err.message,
field: err.details.field
});
}
if (err instanceof AuthenticationError) {
return res.status(401).json({
error: 'Authentication Failed',
message: err.message
});
}
// Generic error
res.status(500).json({
error: 'Internal Server Error',
message: process.env.NODE_ENV === 'production'
? 'An error occurred'
: err.message
});
};
// Try/catch with proper cleanup
const processFile = async (filePath) => {
const fileHandle = await fs.open(filePath, 'r');
try {
const content = await fileHandle.readFile('utf8');
return JSON.parse(content);
} catch (error) {
throw new ProcessingError('Failed to process file', error);
} finally {
await fileHandle.close(); // Always cleanup
}
};
```
### Async Patterns
**Modern Async/Await Patterns:**
```javascript
// Parallel execution with Promise.all
const fetchUserData = async (userId) => {
const [profile, orders, preferences] = await Promise.all([
fetchProfile(userId),
fetchOrders(userId),
fetchPreferences(userId)
]);
return { profile, orders, preferences };
};
// Sequential execution with proper error handling
const updateUserProfile = async (userId, updates) => {
try {
const user = await fetchUser(userId);
const validated = await validateUpdates(updates);
const updated = await saveUser(userId, validated);
await invalidateCache(userId);
await sendNotification(userId, 'Profile updated');
return updated;
} catch (error) {
await rollbackChanges(userId);
throw error;
}
};
// Retry logic with exponential backoff
const fetchWithRetry = async (url, maxRetries = 3) => {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
return await fetch(url);
} catch (error) {
if (attempt === maxRetries - 1) throw error;
const delay = Math.pow(2, attempt) * 1000;
await new Promise(resolve => setTimeout(resolve, delay));
}
}
};
// Concurrent with limit
const processBatch = async (items, concurrency = 5) => {
const results = [];
for (let i = 0; i < items.length; i += concurrency) {
const batch = items.slice(i, i + concurrency);
const batchResults = await Promise.all(
batch.map(item => processItem(item))
);
results.push(...batchResults);
}
return results;
};
```
### Security Considerations
**Input Validation:**
```javascript
// Using validator.js
import validator from 'validator';
const validateUserInput = (data) => {
const errors = {};
// Email validation
if (!data.email || !validator.isEmail(data.email)) {
errors.email = 'Valid email required';
}
// Password strength
if (!data.password || !validator.isStrongPassword(data.password, {
minLength: 8,
minLowercase: 1,
minUppercase: 1,
minNumbers: 1,
minSymbols: 1
})) {
errors.password = 'Password must be at least 8 characters with uppercase, lowercase, number, and symbol';
}
// Username sanitization
if (data.username) {
data.username = validator.escape(data.username);
}
if (Object.keys(errors).length > 0) {
throw new ValidationError('Input validation failed', errors);
}
return data;
};
// SQL injection prevention (parameterized queries)
const getUserByEmail = async (email) => {
// ✅ Good: Parameterized query
const query = 'SELECT * FROM users WHERE email = ?';
return await db.query(query, [email]);
// ❌ Bad: String concatenation (SQL injection!)
// const query = `SELECT * FROM users WHERE email = '${email}'`;
};
// XSS prevention
import DOMPurify from 'isomorphic-dompurify';
const sanitizeHTML = (html) => {
return DOMPurify.sanitize(html, {
ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'p'],
ALLOWED_ATTR: []
});
};
```
**Secrets Management:**
```javascript
// ❌ Never commit secrets
// const API_KEY = "sk-1234567890abcdef";
// ✅ Use environment variables
import dotenv from 'dotenv';
dotenv.config();
const config = {
apiKey: process.env.API_KEY,
dbUrl: process.env.DATABASE_URL,
jwtSecret: process.env.JWT_SECRET
};
// Validate required env vars
const requiredEnvVars = ['API_KEY', 'DATABASE_URL', 'JWT_SECRET'];
for (const varName of requiredEnvVars) {
if (!process.env[varName]) {
throw new Error(`Missing required environment variable: ${varName}`);
}
}
```
**NIST Control Tags:**
```javascript
// @nist ia-2 "User authentication"
// @nist ia-5.1 "Password-based authentication"
export const authenticateUser = async (username, password) => {
// Implementation
};
// @nist ac-3 "Access enforcement"
// @nist ac-6 "Least privilege"
export const checkPermissions = (user, resource, action) => {
// Implementation
};
// @nist sc-8 "Transmission confidentiality"
// @nist sc-13 "Cryptographic protection"
export const encryptData = (data) => {
// Implementation
};
```
**See Also:** [NIST Implementation Guide](../../../docs/nist/NIST_IMPLEMENTATION_GUIDE.md)
---
## Level 3: Mastery Resources
### Advanced Topics
- **[Advanced Patterns](resources/advanced-patterns.md)**: Generators, proxies, decorators, metaprogramming
- **[Architecture Patterns](resources/architecture-patterns.md)**: Clean architecture, event-driven, microservices
- **[Performance Optimization](resources/performance.md)**: Profiling, memoization, lazy loading, code splitting
### Templates & Examples
- **[Express API Template](templates/express-api-template/)**: Complete REST API with auth, DB, tests
- **[React App Template](templates/react-app-template/)**: Modern React app with routing, state management
- **[Test Template](templates/test-template.js)**: Jest template with mocks and patterns
- **[Package Template](templates/package-template/)**: npm package with CI/CD
### Configuration Files
- **[.eslintrc.json](resources/configs/.eslintrc.json)**: ESLint configuration
- **[.prettierrc](resources/configs/.prettierrc)**: Prettier configuration
- **[jest.config.json](resources/configs/jest.config.json)**: Jest configuration
- **[package.json](resources/configs/package.json)**: Example package.json
### Tools & Scripts
- **[setup-project.sh](scripts/setup-project.sh)**: Initialize new JavaScript project
- **[check-quality.sh](scripts/check-quality.sh)**: Run all quality checks
- **[deploy.sh](scripts/deploy.sh)**: Deployment script
### Related Skills
- [TypeScript Coding Standards](../typescript/SKILL.md) - TypeScript-specific practices
- [Testing Standards](../../testing/unit-testing/SKILL.md) - Comprehensive testing
- [Security Standards](../../security/authentication/SKILL.md) - Security implementation
---
## Quick Reference Commands
```bash
# Setup
npm init -y
npm install --save-dev eslint prettier jest
# Linting & formatting
npx eslint --fix src/
npx prettier --write src/
# Testing
npm test
npm test -- --coverage
npm test -- --watch
# Build & run
npm run build
npm start
# Security audit
npm audit
npm audit fix
```
---
## Examples
### Basic Usage
```javascript
// TODO: Add basic example for javascript
// This example demonstrates core functionality
```
### Advanced Usage
```javascript
// TODO: Add advanced example for javascript
// This example shows production-ready patterns
```
### Integration Example
```javascript
// TODO: Add integration example showing how javascript
// works with other systems and services
```
See `examples/javascript/` for complete working examples.
## Integration Points
This skill integrates with:
### Upstream Dependencies
- **Tools**: Common development tools and frameworks
- **Prerequisites**: Basic understanding of general concepts
### Downstream Consumers
- **Applications**: Production systems requiring javascript functionality
- **CI/CD Pipelines**: Automated testing and deployment workflows
- **Monitoring Systems**: Observability and logging platforms
### Related Skills
- See other skills in this category
### Common Integration Patterns
1. **Development Workflow**: How this skill fits into daily development
2. **Production Deployment**: Integration with production systems
3. **Monitoring & Alerting**: Observability integration points
## Common Pitfalls
### Pitfall 1: Insufficient Testing
**Problem:** Not testing edge cases and error conditions leads to production bugs
**Solution:** Implement comprehensive test coverage including:
- Happy path scenarios
- Error handling and edge cases
- Integration points with external systems
**Prevention:** Enforce minimum code coverage (80%+) in CI/CD pipeline
### Pitfall 2: Hardcoded Configuration
**Problem:** Hardcoding values makes applications inflexible and environment-dependent
**Solution:** Use environment variables and configuration management:
- Separate config from code
- Use environment-specific configuration files
- Never commit secrets to version control
**Prevention:** Use tools like dotenv, config validators, and secret scanners
### Pitfall 3: Ignoring Security Best Practices
**Problem:** Security vulnerabilities from not following established security patterns
**Solution:** Follow security guidelines:
- Input validation and sanitization
- Proper authentication and authorization
- Encrypted data transmission (TLS/SSL)
- Regular security audits and updates
**Prevention:** Use security linters, SAST tools, and regular dependency updates
**Best Practices:**
- Follow established patterns and conventions for javascript
- Keep dependencies up to date and scan for vulnerabilities
- Write comprehensive documentation and inline comments
- Use linting and formatting tools consistently
- Implement proper error handling and logging
- Regular code reviews and pair programming
- Monitor production metrics and set up alerts
---
## Validation
This skill has been validated with:
- ✅ Token count: Level 1 <2,000, Level 2 <5,000
- ✅ Code examples: All tested and working
- ✅ Links: All internal references valid
- ✅ Resources: All bundled files created
- ✅ YAML frontmatter: Valid and completeRelated Skills
performance-testing-standards
Performance testing standards for load, stress, spike, and soak testing. Covers k6 and JMeter implementation, SLI/SLO definitions, CI/CD integration, and bottleneck analysis. Use when validating system behavior under load, establishing baselines, or capacity planning.
e2e-testing-standards
Implement robust E2E tests with Playwright or Cypress using Page Object Model, proper waits, and CI/CD integration. Covers selector strategies, flaky test prevention, and cross-browser testing patterns.
typescript-coding-standards
TypeScript coding standards covering strict type system, advanced types, decorators, generics, and best practices for type-safe applications. Use for TypeScript projects requiring robust type safety and maintainable code.
swift-coding-standards
Master Swift coding standards with Apple's guidelines, protocol-oriented design, and modern concurrency patterns
shell-scripting-standards
Essential patterns for reliable shell scripts - portable shebangs, error handling, quoting rules, functions, testing with Bats, and ShellCheck integration.
rust-coding-standards
Master Rust's ownership system, type safety, and zero-cost abstractions for building safe, concurrent, and performant systems. Covers borrowing, lifetimes, traits, error handling, async/await, and testing patterns.
python-coding-standards
Python coding standards following PEP 8, type hints, testing best practices, and modern Python patterns. Use for Python projects requiring clean, maintainable, production-ready code with comprehensive testing.
kotlin-coding-standards
Master Kotlin coding standards with null safety, coroutines, and idiomatic patterns. Use when developing JVM/Android applications requiring type-safe async programming.
go-coding-standards
Go coding standards following idiomatic Go patterns, error handling, concurrency best practices, and modern Go tooling. Use for Go projects requiring clean, efficient, production-ready code with comprehensive testing.
coding-standards
Comprehensive coding standards and best practices for maintainable, consistent software development across multiple languages and paradigms
too-long-level1
A skill with excessively long Level 1 section
Referenced Skill
No description provided.