| name | JavaScript |
| license | MIT |
| description | A comprehensive JavaScript style guide skill. When activated, it provides best-practice JavaScript coding conventions and generates code that strictly follows the style guide, covering variables, functions, objects, arrays, classes, modules, async patterns, error handling, naming conventions, and more.
|
JavaScript Style Guide Skill
Activation
This skill activates when the user mentions or implies JavaScript in their request. Once activated, it:
- Responds with best-practice guidance
- Generates JavaScript code that strictly conforms to the style guide
- Provides explanations for why each convention is recommended
Complete Style Rules
1. References
- Use
const for all references; avoid var.
- If you must reassign references, use
let instead of var.
- Both
const and let are block-scoped, whereas var is function-scoped.
var count = 1;
const count = 1;
let mutableValue = 1;
mutableValue += 1;
2. Objects
- Use literal syntax for object creation.
- Use computed property names when creating objects with dynamic property names.
- Use object method shorthand and property value shorthand.
- Group shorthand properties at the beginning of the object declaration.
- Only quote properties that are invalid identifiers.
- Prefer the object spread syntax (
...) over Object.assign to shallow-copy objects.
const item = new Object();
const item = {};
const key = 'name';
const obj = { [key]: 'value' };
const name = 'Alice';
const atom = {
name,
value: 1,
addValue(val) {
return atom.value + val;
},
};
const original = { a: 1, b: 2 };
const copy = { ...original, c: 3 };
3. Arrays
- Use literal syntax for array creation.
- Use
Array.from or the spread operator to convert array-like objects.
- Use
return statements in array method callbacks.
- Use line breaks after the opening bracket and before the closing bracket if the array has multiple lines.
const items = new Array();
const items = [];
const nodes = Array.from(document.querySelectorAll('.item'));
const uniqueValues = [...new Set(arr)];
[1, 2, 3].map((x) => x + 1);
[1, 2, 3].map((x) => {
const y = x + 1;
return x * y;
});
4. Destructuring
- Use object destructuring when accessing multiple properties of an object.
- Use array destructuring.
- Use object destructuring for multiple return values, not array destructuring.
function getFullName(user) {
const firstName = user.firstName;
const lastName = user.lastName;
return `${firstName} ${lastName}`;
}
function getFullName({ firstName, lastName }) {
return `${firstName} ${lastName}`;
}
const [first, , third] = [1, 2, 3];
function processInput(input) {
return { left, right, top, bottom };
}
const { left, top } = processInput(input);
5. Strings
- Use single quotes
'' for strings.
- Use template literals for string interpolation and multi-line strings.
- Never use
eval() on a string.
- Do not unnecessarily escape characters in strings.
const name = "Alice";
const greeting = 'Hello, ' + name + '!';
const name = 'Alice';
const greeting = `Hello, ${name}!`;
6. Functions
- Use named function expressions instead of function declarations.
- Wrap immediately invoked function expressions (IIFE) in parentheses.
- Never declare a function in a non-function block (
if, while, etc.).
- Never name a parameter
arguments.
- Use default parameter syntax rather than mutating function arguments.
- Always put default parameters last.
- Never use the
Function constructor to create a new function.
- Use the spread operator
... to call variadic functions.
- Use rest parameters (
...args) instead of arguments.
const short = function longUniqueMoreDescriptiveLexicalFoo() {
};
function handleThings(name, opts = {}) {
}
function concatenateAll(...args) {
return args.join('');
}
const values = [1, 2, 3];
console.log(Math.max(...values));
7. Arrow Functions
- Use arrow function notation for anonymous functions (callbacks).
- If the function body consists of a single expression, omit the braces and use the implicit return.
- If the expression spans multiple lines, wrap it in parentheses for readability.
- Always include parentheses around arguments for clarity and consistency.
[1, 2, 3].map(function (x) {
const y = x + 1;
return x * y;
});
[1, 2, 3].map((x) => {
const y = x + 1;
return x * y;
});
[1, 2, 3].map((x) => x * 2);
[1, 2, 3].map((number) => (
`A long string with the ${number}. It's so long that we don't want it to take up space on the .map line!`
));
8. Classes & Constructors
- Always use
class; avoid manipulating prototype directly.
- Use
extends for inheritance.
- Methods can return
this to enable method chaining.
- Classes have a default constructor if no constructor is specified; an empty constructor or one that just delegates to a parent is unnecessary.
- Avoid duplicate class members.
function Queue(contents = []) {
this.queue = [...contents];
}
Queue.prototype.pop = function () {
return this.queue.pop();
};
class Queue {
constructor(contents = []) {
this.queue = [...contents];
}
pop() {
return this.queue.pop();
}
}
class PeekableQueue extends Queue {
peek() {
return this.queue[0];
}
}
9. Modules
- Always use ES modules (
import/export) over a non-standard module system.
- Do not use wildcard imports.
- Do not export directly from an import.
- Only import from a path in one place.
- Do not export mutable bindings.
- Prefer default export for modules that only export a single thing.
- Put all
imports above non-import statements.
- Multi-line imports should be indented like multi-line array and object literals.
const utils = require('./utils');
module.exports = utils.fetchData;
import { fetchData } from './utils';
export default fetchData;
import { named1, named2 } from 'module';
import {
longNameA,
longNameB,
longNameC,
} from 'path/to/module';
10. Iterators and Generators
- Prefer JavaScript's higher-order functions over
for-in or for-of loops.
- Use
map, filter, reduce, find, findIndex, every, some, etc.
- Don't use generators for now (if targeting ES5 environments).
const numbers = [1, 2, 3, 4, 5];
let sum = 0;
for (const num of numbers) {
sum += num;
}
const sum = numbers.reduce((total, num) => total + num, 0);
const evens = numbers.filter((num) => num % 2 === 0);
11. Properties
- Use dot notation when accessing properties.
- Use bracket notation
[] when accessing properties with a variable.
- Use the exponentiation operator
** instead of Math.pow.
const luke = { jedi: true, age: 28 };
const isJedi = luke.jedi;
const prop = 'jedi';
const isJedi = luke[prop];
const result = 2 ** 10;
12. Variables
- Always use
const or let; never use var.
- Use one
const or let declaration per variable or assignment.
- Group all
consts and then group all lets.
- Assign variables where you need them, but place them in a reasonable place.
- Don't chain variable assignments.
- Avoid using unary increments (
++, --); use += 1 / -= 1 instead.
- Avoid linebreaks before or after
= in an assignment.
const items = getItems(),
goSportsTeam = true,
dragonball = 'z';
const items = getItems();
const goSportsTeam = true;
const dragonball = 'z';
const a = 1;
const b = 2;
let c = 3;
let d = 4;
let count = 0;
count += 1;
13. Hoisting
var declarations get hoisted; const and let are in Temporal Dead Zone.
- Named function expressions hoist the variable name but not the function body.
- Function declarations hoist the name and the function body.
14. Comparison Operators & Equality
- Use
=== and !== over == and !=.
- Use shortcuts for booleans, but explicit comparisons for strings and numbers.
- Use braces to create blocks in
case and default clauses that contain lexical declarations.
- Ternaries should not be nested and generally be single-line expressions.
- Avoid unneeded ternary statements.
- When mixing operators, enclose them in parentheses (except
**, +, -).
if (isValid == true) { }
if (name != '') { }
if (isValid) { }
if (name !== '') { }
if (collection.length > 0) { }
const thing = foo === 123 ? bar : foobar;
15. Blocks
- Use braces with all multiline blocks.
- Put
else on the same line as the if block's closing brace.
- If an
if block always executes a return, the subsequent else block is unnecessary.
if (test)
return false;
if (test) return false;
if (test) {
return false;
}
if (test) {
thing1();
} else {
thing2();
}
16. Control Statements
- If a control statement (
if, while, etc.) gets too long, each grouped condition should be on a new line, with the logical operator at the beginning of the line.
- Don't use selection operators in place of control statements.
if (
foo === 123
&& bar === 'abc'
) {
thing1();
}
17. Comments
- Use
/** ... */ for multiline comments.
- Use
// for single-line comments. Place them on a new line above the subject.
- Start all comments with a space for readability.
- Prefix comments with
FIXME: or TODO: to annotate problems or suggest actions.
const active = true;
function make(tag) {
return document.createElement(tag);
}
18. Whitespace
- Use soft tabs (spaces) set to 2 spaces.
- Place 1 space before the leading brace.
- Place 1 space before the opening parenthesis in control statements.
- Set off operators with spaces.
- End files with a single newline character.
- Use indentation when making long method chains (more than 2 method chains).
- Leave a blank line after blocks and before the next statement.
- Do not pad blocks with blank lines.
- Do not use multiple blank lines to pad your code.
- Do not add spaces inside parentheses, brackets.
- Add spaces inside curly braces.
function foo(){
const name='Alice';
}
function foo() {
const name = 'Alice';
}
$('#items')
.find('.selected')
.highlight()
.end()
.find('.open')
.updateCount();
19. Commas
- Do not use leading commas.
- Use trailing commas (dangling commas) for multiline structures.
const hero = {
firstName: 'Ada'
, lastName: 'Lovelace'
};
const hero = {
firstName: 'Ada',
lastName: 'Lovelace',
};
const heroes = [
'Batman',
'Superman',
];
20. Semicolons
const name = 'Alice'
const name = 'Alice';
21. Type Casting & Coercion
- Perform type coercion at the beginning of the statement.
- Use
String() for strings, Number() for numbers, Boolean() or !! for booleans.
- Use
parseInt always with a radix.
const val = '4';
const totalScore = val + 0;
const totalScore = Number(val);
const inputValue = String(someNum);
const hasAge = Boolean(age);
const hasName = !!name;
const count = parseInt(inputValue, 10);
22. Naming Conventions
- Avoid single-letter names; be descriptive.
- Use camelCase for objects, functions, and instances.
- Use PascalCase for classes and constructors.
- Use UPPERCASE_SNAKE_CASE for constants that are exported and truly immutable.
- Do not use trailing or leading underscores.
- A base filename should exactly match the name of its default export.
- Use camelCase when exporting a function; use PascalCase when exporting a class / constructor / singleton / function library / bare object.
- Acronyms and initialisms should always be all uppercased or all lowercased.
const OBJEcttsssss = {};
function c() {}
const u = new user();
const thisIsMyObject = {};
function calculateTotal() {}
const user = new User();
export const API_BASE_URL = 'https://api.example.com';
export const MAX_RETRY_COUNT = 3;
23. Accessors
- Accessor functions for properties are not required.
- Do not use JavaScript getters/setters as they cause unexpected side effects.
- If you do make accessor functions, use
getVal() and setVal('value').
- If the property/method is a boolean, use
isVal() or hasVal().
dragon.age();
dragon.getAge();
dragon.setAge(25);
dragon.isAlive();
dragon.hasWings();
24. Events
- When attaching data payloads to events, pass an object (hash) instead of a raw value.
emitter.emit('itemUpdate', item.id);
emitter.emit('itemUpdate', { itemId: item.id });
25. Promises & Async/Await
- Prefer
async/await over chaining .then() and .catch().
- Always handle errors with
try...catch in async functions.
- Avoid mixing callbacks and promises.
- Use
Promise.all for concurrent independent async operations.
- Use
Promise.allSettled when you need results of all promises regardless of rejection.
function fetchData() {
return getData()
.then((data) => parseData(data))
.then((parsed) => validate(parsed))
.catch((err) => console.error(err));
}
async function fetchData() {
try {
const data = await getData();
const parsed = await parseData(data);
return validate(parsed);
} catch (err) {
console.error(err);
throw err;
}
}
async function loadDashboard() {
const [user, posts, notifications] = await Promise.all([
fetchUser(),
fetchPosts(),
fetchNotifications(),
]);
return { user, posts, notifications };
}
26. Error Handling
- Only throw
Error objects (or subclasses of Error).
- Always catch errors where they can be meaningfully handled.
- Use custom error classes for domain-specific errors.
throw 'Something went wrong';
throw { message: 'error' };
throw new Error('Something went wrong');
class ValidationError extends Error {
constructor(message, field) {
super(message);
this.name = 'ValidationError';
this.field = field;
}
}
throw new ValidationError('Invalid email', 'email');
27. Optional Chaining & Nullish Coalescing
- Use optional chaining (
?.) to access nested properties that may not exist.
- Use nullish coalescing (
??) instead of || when you want to allow falsy values like 0 or ''.
const city = user && user.address && user.address.city;
const port = config.port || 3000;
const city = user?.address?.city;
const port = config.port ?? 3000;
28. Standard Library
- Use
Number.isNaN instead of global isNaN.
- Use
Number.isFinite instead of global isFinite.
isNaN('1.2');
isFinite('2e3');
Number.isNaN('1.2');
Number.isFinite('2e3');
Usage
This is a Prompt-based Skill (natural language activation).
How to Use
-
Automatic Activation: Simply mention "JavaScript" in your request. The skill will be activated automatically.
-
Ask for Style Guidance:
"How should I write a JavaScript function that fetches user data?"
-
Request Code Review:
"Review this JavaScript code for style issues: [paste code]"
-
Generate Compliant Code:
"Write a JavaScript module to handle form validation"
-
Ask About Specific Rules:
"What's the correct way to declare variables in JavaScript?"
"How should I handle async errors in JavaScript?"
Examples
User: Write a JavaScript utility function to deep clone an object.
Skill Response: Generates clean, style-guide-compliant code:
function deepClone(source) {
if (typeof structuredClone === 'function') {
return structuredClone(source);
}
return JSON.parse(JSON.stringify(source));
}
export default deepClone;