| name | javascript |
| description | This skill should be used when the user asks to "write JavaScript code", "follow JavaScript style guide", "format JS files", "create Node.js scripts", or needs guidance on JavaScript/Node.js coding standards and best practices. |
JavaScript/Node.js Style Guide
Apply Google JavaScript Style Guide conventions to JavaScript and Node.js code. This skill provides essential coding standards, formatting rules, and best practices for writing clean, maintainable JavaScript.
Note: Google recommends migrating to TypeScript. This guide is for JavaScript projects that have not yet migrated.
Core Principles
File Basics
File naming:
- Use lowercase only
- Use underscores (
_) or dashes (-) but no other punctuation
- Extension must be
.js
- Examples:
my_module.js, user-service.js
File encoding:
- UTF-8 only
- Use special escape sequences for special characters (
\', \", \\, \b, \f, \n, \r, \t, \v)
- For non-ASCII: use actual Unicode character (e.g.,
∞) or hex escape (e.g., \u221e) based on readability
Indentation:
- Use 2 spaces (never tabs)
- No trailing whitespace
Module System
ES Modules (Preferred)
Use import and export statements:
import './sideeffects.js';
import * as goog from '../closure/goog/goog.js';
import {name, value} from './sibling.js';
export class Foo { ... }
export function bar() { ... }
class Foo { ... }
function bar() { ... }
export {Foo, bar};
Import rules:
- Include
.js extension in paths (required)
- Use
lowerCamelCase for module import names: import * as fileOne from '../file-one.js';
- Keep same name for named imports, avoid aliasing unless necessary
- Do not use default exports
- Import statements are exception to 80-column limit (do not wrap)
Avoid circular dependencies - Do not create import cycles between modules.
Variable Declarations
Use const and let
const MAX_COUNT = 100;
const users = [];
let currentIndex = 0;
One variable per declaration:
const a = 1;
const b = 2;
const a = 1, b = 2;
Declare close to first use:
function process(items) {
const result = items.map(x => x * 2);
return result;
}
Formatting
Braces
K&R style (Egyptian brackets):
class InnerClass {
constructor() {}
method(foo) {
if (condition(foo)) {
try {
something();
} catch (err) {
recover();
}
}
}
}
Rules:
- No line break before opening brace
- Line break after opening brace
- Line break before closing brace
- Line break after closing brace (except before
else, catch, while, comma, semicolon)
Always use braces for control structures (even single statements):
if (condition) {
doSomething();
}
if (shortCondition()) foo();
if (condition)
doSomething();
Column Limit
80 characters with exceptions:
import and export from statements
- Long URLs, shell commands, file paths in comments
- Lines where wrapping is impossible
Line Wrapping
Break at higher syntactic levels:
currentEstimate =
calc(currentEstimate + x * currentEstimate) /
2.0;
currentEstimate = calc(currentEstimate + x *
currentEstimate) / 2.0;
Continuation lines: indent at least +4 spaces from original line.
Whitespace
Horizontal spacing:
- Space after reserved words:
if (, for (, catch (
- No space for
function and super: function(, super(
- Space before opening brace:
if (x) {, class Foo {
- Space around binary/ternary operators:
a + b, x ? y : z
- Space after comma/semicolon:
foo(a, b);
- Space after colon in objects:
{a: 1, b: 2}
- Space around
//: // comment
Vertical spacing:
- Blank line between methods
- Blank lines within methods to create logical groups (sparingly)
Semicolons
Required - Every statement must end with semicolon:
const x = 1;
doSomething();
Arrays and Objects
Array Literals
const values = [
'first value',
'second value',
];
const a = [x1, x2, x3];
const b = new Array(x1, x2, x3);
const [a, b, c, ...rest] = generateResults();
let [, b,, d] = someArray;
[...foo]
[...foo, ...bar]
Object Literals
const obj = {
a: 0,
b: 1,
};
const o = {a: 0, b: 1};
const o = new Object();
{
width: 42,
height: 50,
}
{
'width': 42,
'maxWidth': 43,
}
{
width: 42,
'maxWidth': 43,
}
const obj = {
value: 1,
method() {
return this.value;
},
};
const foo = 1;
const bar = 2;
const obj = {foo, bar};
function process({num, str = 'default'} = {}) {}
Classes
Class Declaration
class MyClass {
constructor(value) {
this.value_ = value;
this.mutableField = 0;
}
getValue() {
return this.value_;
}
toString() {
return `MyClass(${this.value_})`;
}
}
class ChildClass extends MyClass {
constructor(value, extra) {
super(value);
this.extra = extra;
}
}
Rules:
- Constructors are optional
- Define all fields in constructor
- Use
@const for never-reassigned fields
- Use
@private, @protected for non-public fields
- Private field names may end with underscore
- No semicolons after methods
- Call
super() before accessing this in subclasses
Functions
Arrow Functions
Preferred for callbacks and short functions:
const squares = numbers.map(n => n * n);
items.forEach((item) => {
process(item);
});
class Timer {
start() {
setInterval(() => {
this.tick();
}, 1000);
}
}
Rules:
- Prefer arrow functions for callbacks
- Use arrow functions to preserve
this binding
- Omit parens for single parameter:
x => x * 2
- Use parens for zero or multiple params:
() => 42, (a, b) => a + b
- Always use braces for multi-line bodies
Function Declarations
function myFunction(param1, param2) {
return param1 + param2;
}
function greet(name = 'Guest') {
return `Hello, ${name}`;
}
function sum(...numbers) {
return numbers.reduce((a, b) => a + b, 0);
}
Control Structures
Conditionals
if (condition) {
doSomething();
} else if (otherCondition) {
doOther();
} else {
doDefault();
}
const value = condition ? trueValue : falseValue;
Loops
for (const item of items) {
process(item);
}
for (let i = 0; i < array.length; i++) {
process(array[i]);
}
for (const key in object) {
if (object.hasOwnProperty(key)) {
process(object[key]);
}
}
Switch Statements
switch (value) {
case 'option1':
handleOption1();
break;
case 'option2':
handleOption2();
break;
default:
handleDefault();
}
Modern Features
Template Literals
const message = `Hello, ${name}!`;
const html = `
<div>
<h1>${title}</h1>
</div>
`;
Promises and Async/Await
async function fetchData() {
try {
const response = await fetch(url);
const data = await response.json();
return data;
} catch (error) {
console.error('Failed:', error);
throw error;
}
}
fetch(url)
.then(response => response.json())
.then(data => process(data))
.catch(error => console.error(error));
Comments
Implementation Comments
someFunction(obviousParam, true, 'hello');
JSDoc
Use JSDoc for:
- All classes
- All methods and functions (public and private)
- Properties when needed for clarity
function greet(name, age) {
return `Hello, ${name}`;
}
class Point {
constructor(x, y) {
this.x_ = x;
this.y_ = y;
}
}
Node.js Specific
Module Exports
export class Service {}
export function helper() {}
class Service {}
function helper() {}
module.exports = {Service, helper};
Error Handling
async function processFile(path) {
try {
const content = await fs.promises.readFile(path, 'utf8');
return JSON.parse(content);
} catch (error) {
console.error(`Failed to process ${path}:`, error);
throw error;
}
}
throw new Error('Something went wrong');
throw new TypeError('Expected string');
Common Patterns
Object Property Access
if (obj.property != null) {
}
const value = obj?.deeply?.nested?.property;
const result = value ?? defaultValue;
Array Operations
const doubled = numbers.map(n => n * 2);
const evens = numbers.filter(n => n % 2 === 0);
const sum = numbers.reduce((acc, n) => acc + n, 0);
if (array.includes(item)) { }
const found = array.find(item => item.id === targetId);
Quick Reference
Variable declaration: const (default), let (when reassignment needed), never var
Indentation: 2 spaces
Semicolons: Required
String quotes: Single ' or backticks ` for templates
Braces: K&R style, always use for control structures
Line length: 80 characters
Naming: lowerCamelCase for variables/functions, UpperCamelCase for classes
Imports: Use .js extension, no default exports
Comments: // for single-line, /* */ for multi-line
Additional Resources
Reference Files
For comprehensive coverage of specific topics:
references/advanced-features.md - Advanced JavaScript patterns, promises, generators, proxies
references/jsdoc-guide.md - Complete JSDoc annotation guide
references/naming-conventions.md - Detailed naming rules for all identifier types
references/disallowed-features.md - Features to avoid and their alternatives
Complete Style Guide
The full Google JavaScript Style Guide is available at:
https://google.github.io/styleguide/jsguide.html