home / skills / next-friday / nextfriday-skills / nextfriday-code-style

nextfriday-code-style skill

/skills/nextfriday-code-style

This skill enforces Next Friday code style rules for clean, readable TypeScript with guards, async/await, and proper exports.

npx playbooks add skill next-friday/nextfriday-skills --skill nextfriday-code-style

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
2.6 KB
---
name: nextfriday-code-style
description: Next Friday code style rules for formatting, structure, and readability. Use when writing functions, conditionals, or organizing code.
user-invocable: false
---

# Next Friday Code Style

Rules for code formatting, structure, and readability.

## Control Flow

### Guard Clauses

Use early returns instead of nested if statements.

```typescript
// Bad:
function processData(data: Data | null): Item[] {
  if (data) {
    if (data.items) {
      return data.items.map(formatItem);
    }
  }
  return [];
}

// Good:
function processData(data: Data | null): Item[] {
  if (!data) return [];
  if (!data.items) return [];

  return data.items.map(formatItem);
}
```

### No Nested Ternary

Use functions with early returns instead.

```typescript
// Bad:
const status = isLoading ? "loading" : hasError ? "error" : "success";

// Good:
function getStatus(): string {
  if (isLoading) return "loading";
  if (hasError) return "error";

  return "success";
}
```

## Async Code

### Prefer async/await

No `.then()` promise chains.

```typescript
// Bad:
fetchData(url)
  .then((response) => response.json())
  .then((data) => setData(data));

// Good:
async function loadData(): Promise<void> {
  const response = await fetchData(url);
  const data = await response.json();
  setData(data);
}
```

## Functions

### Function Declarations

Use declarations over arrow functions in `.ts` files.

```typescript
// Bad:
const formatDate = (date: Date): string => {
  return date.toLocaleDateString();
};

// Good:
function formatDate(date: Date): string {
  return date.toLocaleDateString();
}
```

### Separate Exports

Declare first, export after.

```typescript
// Bad:
export function fetchData() {}

// Good:
function fetchData() {}
export { fetchData };
```

## Formatting

### Curly Braces

Single-line: no braces. Multi-line: require braces.

```typescript
// Bad:
if (!data) { return null; }

// Good:
if (!data) return null;
```

### Extract Complexity

Move complex expressions out of return statements and function parameters.

```typescript
// Bad:
return isActive ? "Active" : "Inactive";
processData(value ?? defaultValue);

// Good:
const label = isActive ? "Active" : "Inactive";
return label;

const data = value ?? defaultValue;
processData(data);
```

### Blank Lines

Add blank lines after multi-line blocks and before return statements.

```typescript
// Good:
const config = {
  baseUrl: process.env.API_URL,
  timeout: 5000,
};

const item = items.find((item) => item.id === id);

return item;
```

### Sorted Destructuring

Alphabetical order, defaults first.

```typescript
// Good:
const { count = 0, status = "active", id, name } = data;
```

Overview

This skill codifies the Next Friday code style rules for formatting, structure, and readability. It provides concrete guidance for writing functions, control flow, async code, and formatting so code remains predictable and easy to review.

How this skill works

The skill inspects code patterns and recommends replacements that follow Next Friday conventions: prefer guard clauses, avoid nested ternaries, use async/await, prefer function declarations in TypeScript, and enforce simple formatting rules like when to use braces and blank lines. It suggests refactors that simplify returns, extract complex expressions, and keep destructuring sorted and predictable.

When to use it

  • When writing or refactoring functions to improve clarity and testability.
  • When converting promise chains into async/await flows.
  • When reviewing pull requests to enforce consistent control flow and formatting.
  • When organizing exports and declarations in TypeScript modules.
  • When cleaning up complex return statements or nested conditionals.

Best practices

  • Use early returns (guard clauses) instead of nested ifs to reduce indentation and cognitive load.
  • Replace nested ternary operators with small helper functions that return early.
  • Prefer async/await over .then() chains to keep async logic linear and readable.
  • Declare functions (not arrow constants) in TypeScript files and export separately after declaration.
  • Keep single-line statements without braces; require braces for multi-line blocks. Add blank lines after multi-line blocks and before returns.
  • Extract complex expressions into named constants before using them in returns or parameters; sort destructured properties alphabetically with defaults first.

Example use cases

  • Refactor a deeply nested if/else block into guard clauses for faster reasoning and fewer side effects.
  • Convert chained Promise calls into an async function to simplify error handling and flow.
  • Standardize module structure by declaring functions first and exporting them in one place.
  • Clean up a long return statement by extracting intermediate values into clearly named variables.
  • Reformat destructuring in a component to alphabetical order with defaults for consistent diffs and readability.

FAQ

Why prefer function declarations over arrow functions in TypeScript?

Function declarations provide clearer stack traces, consistent hoisting behavior, and a recognizable pattern for public module APIs.

When is a ternary acceptable?

Use a ternary only for very short, single-expression choices. Replace nested or multi-branch ternaries with small functions and early returns.