Repository: spotify/backstage
File: packages/ui/src/hooks/useBreakpoint.ts (TypeScript)

Code before:
function bpIndex(key: Breakpoint): number {
  return breakpointIndex.get(key) ?? 0;
}

const IS_SERVER =
  typeof window === 'undefined' || typeof window.matchMedia === 'undefined';

function computeBreakpoint(): Breakpoint {
  if (IS_SERVER) {
    return 'initial';
  }
  for (let i = breakpoints.length - 1; i >= 0; i--) {
    if (window.matchMedia(`(min-width: ${breakpoints[i].value}px)`).matches) {
      return breakpoints[i].id;
    }
  }
  return 'initial';
}

// --- Singleton store ---
// `current` is initialized lazily on first client-side access.
// `listeners` is eagerly initialized since Set is safe to create on the server.

let current: Breakpoint | undefined;
const listeners = new Set<() => void>();
let initialized = false;

function ensureInitialized(): void {
  if (initialized || IS_SERVER) {
    return;
  }
  initialized = true;
  current = computeBreakpoint();

  // Register one listener per breakpoint. When any query fires, re-evaluate
  // all breakpoints to find the new active one. Notify subscribers only if
  // the active breakpoint actually changed.
  for (const bp of breakpoints) {
    const mql = window.matchMedia(`(min-width: ${bp.value}px)`);
    mql.addEventListener('change', () => {
      const next = computeBreakpoint();
      if (next !== current) {
        current = next;
        for (const cb of listeners) {
          cb();
        }
      }
    });
  }
}


Review comment (refactor):
Just so there's no surprise: this will still be duplicated across BUI instances, such as different package versions or module federation remotes. From what can tell that's completely fine though.

Maybe make a note that we're not bothering with a global singleton here though. And I don't think we should, because it complicates stability.

Code after:
function bpIndex(key: Breakpoint): number {
  return breakpointIndex.get(key) ?? 0;
}

const IS_SERVER =
  typeof window === 'undefined' || typeof window.matchMedia === 'undefined';

function computeBreakpoint(): Breakpoint {
  if (IS_SERVER) {
    return 'initial';
  }
  for (let i = breakpoints.length - 1; i >= 0; i--) {
    if (window.matchMedia(`(min-width: ${breakpoints[i].value}px)`).matches) {
      return breakpoints[i].id;
    }
  }
  return 'initial';
}

// --- Module-scoped singleton store ---
// This is intentionally not a global singleton. Multiple copies of this module
// (e.g. different package versions or module federation remotes) each get their
// own store. This avoids cross-version coupling at the cost of a few extra
// listeners, which is a fine trade-off.
// `current` is initialized lazily on first client-side access.

let current: Breakpoint | undefined;
const listeners = new Set<() => void>();
let initialized = false;

function ensureInitialized(): void {
  if (initialized || IS_SERVER) {
    return;
  }
  initialized = true;
  current = computeBreakpoint();

  // Register one listener per breakpoint. When any query fires, re-evaluate
  // all breakpoints to find the new active one. Notify subscribers only if
  // the active breakpoint actually changed.
  for (const bp of breakpoints) {
    const mql = window.matchMedia(`(min-width: ${bp.value}px)`);
    mql.addEventListener('change', () => {
      const next = computeBreakpoint();
      if (next !== current) {
        current = next;
        for (const cb of listeners) {
          cb();
        }
      }
    });