Lesson 20 of 54

Code Formatting and Aesthetics

Organizing Code into Paragraphs

Good prose is organized into paragraphs. Each paragraph covers one idea. There's a topic sentence, supporting detail, and then a transition to the next paragraph.

Good code works the same way.

Blank Lines as Thought Separators

A blank line says: "We're moving to a new thought."

Without blank lines, code becomes a wall of text:

Javascript
// BAD: Wall of code
function processCheckout(cart, user) {
  if (!cart.items.length) throw new EmptyCartError();
  if (!user.paymentMethod) throw new NoPaymentMethodError();
  const subtotal = cart.items.reduce((sum, item) => sum + item.price * item.quantity, 0);
  const shipping = calculateShipping(cart, user.address);
  const tax = calculateTax(subtotal, user.address);
  const total = subtotal + shipping + tax;
  const payment = chargePayment(user.paymentMethod, total);
  if (!payment.success) throw new PaymentFailedError(payment.error);
  const order = createOrder(cart, user, payment);
  await saveOrder(order);
  clearCart(cart);
  await sendConfirmationEmail(user.email, order);
  return order;
}

With paragraph breaks:

Javascript
// GOOD: Organized into paragraphs
function processCheckout(cart, user) {
  // Validation
  if (!cart.items.length) throw new EmptyCartError();
  if (!user.paymentMethod) throw new NoPaymentMethodError();
  
  // Calculate totals
  const subtotal = cart.items.reduce((sum, item) => sum + item.price * item.quantity, 0);
  const shipping = calculateShipping(cart, user.address);
  const tax = calculateTax(subtotal, user.address);
  const total = subtotal + shipping + tax;
  
  // Process payment
  const payment = chargePayment(user.paymentMethod, total);
  if (!payment.success) throw new PaymentFailedError(payment.error);
  
  // Create and save order
  const order = createOrder(cart, user, payment);
  await saveOrder(order);
  clearCart(cart);
  
  // Notify customer
  await sendConfirmationEmail(user.email, order);
  
  return order;
}

Now you can scan the structure without reading every line.

One Blank Line vs. Two

Use blank lines consistently:

  • One blank line: Between paragraphs within a function
  • Two blank lines: Between top-level declarations (functions, classes)
Javascript
function firstFunction() {
  // paragraph one
  doSomething();
  
  // paragraph two
  doSomethingElse();
}


function secondFunction() {
  // ...
}


class MyClass {
  // ...
}

The Newspaper Metaphor

A newspaper article is organized top-to-bottom:

  1. Headline: Tells you the story in a few words
  2. Lead paragraph: Summarizes the key points
  3. Supporting details: Increasingly specific information
  4. Background: Context for those who want it

Code should work the same way.

File Organization

At the top of a file, put the important stuff:

Javascript
// 1. Imports (dependencies)
import { Database } from './database';
import { Logger } from './logger';

// 2. Constants/configuration
const MAX_RETRIES = 3;
const TIMEOUT_MS = 5000;

// 3. Main exports (the "headline")
export class OrderService {
  // Public methods first (the interface)
  async createOrder(data) { }
  async getOrder(id) { }
  async cancelOrder(id) { }
  
  // Private methods below (the implementation)
  private validateOrder(data) { }
  private calculateTotal(items) { }
  private notifyWarehouse(order) { }
}

// 4. Helper functions at the bottom
function formatCurrency(cents) { }
function generateOrderId() { }

Readers who just want to use the class can stop at the public interface. Those who need implementation details scroll down.

Function Organization

Within functions, follow the same pattern:

Javascript
async function processRefund(orderId, reason) {
  // 1. Setup and validation (headline)
  const order = await getOrder(orderId);
  validateRefundEligibility(order);
  
  // 2. Main logic (the story)
  const refund = calculateRefund(order);
  await processPayment(order.paymentMethod, -refund.amount);
  
  // 3. Side effects (the details)
  await updateOrderStatus(order, 'refunded');
  await logRefund(order, refund, reason);
  await notifyCustomer(order.customerEmail, refund);
  
  // 4. Return result
  return refund;
}

Variable Declarations

Declare variables close to where they're used, not all at the top:

Javascript
// BAD: All declarations at top
function processData(items) {
  let total = 0;
  let count = 0;
  let average = 0;
  let filtered = [];
  let sorted = [];
  
  // ... 50 lines later, you finally use 'sorted'
  sorted = filtered.sort();
}

// GOOD: Declare when needed
function processData(items) {
  const filtered = items.filter(item => item.isActive);
  
  const total = filtered.reduce((sum, item) => sum + item.value, 0);
  const count = filtered.length;
  const average = count > 0 ? total / count : 0;
  
  const sorted = filtered.sort((a, b) => b.value - a.value);
  
  return { sorted, average };
}

Conceptual Affinity

Code that shares a concept should be close together:

Javascript
// BAD: Related code scattered
function validateUser(user) { }
function processPayment(payment) { }
function validateOrder(order) { }
function processRefund(refund) { }
function validatePayment(payment) { }

// GOOD: Grouped by concept
function validateUser(user) { }
function validateOrder(order) { }
function validatePayment(payment) { }

function processPayment(payment) { }
function processRefund(refund) { }

Or even better, group by feature:

Javascript
// user-validation.js
export function validateUser(user) { }
export function validateUserEmail(email) { }

// payment-processing.js
export function validatePayment(payment) { }
export function processPayment(payment) { }
export function processRefund(refund) { }

The 30-Second Test

Can a developer understand what a file does in 30 seconds?

They should be able to:

  1. Read the filename and understand the domain
  2. Skim the imports and see the dependencies
  3. See the public API at a glance
  4. Understand the main flow without reading every line

If your file fails this test, reorganize it.


Key insight: Use blank lines to separate logical paragraphs. Organize files and functions like newspaper articles: important stuff first, details below. Group conceptually related code together. Make code skimmable.