Skip to content

Scroll Region Optimization (DECSTBM)

Terminal scroll regions allow the terminal emulator to natively shift content up or down within a defined row range, avoiding full re-renders.

How It Works

  1. Set scroll region -- DECSTBM (ESC [ top ; bottom r) restricts scrolling operations to the specified row range.
  2. Scroll content -- SU (ESC [ n S) scrolls up, SD (ESC [ n T) scrolls down within the region.
  3. Reset -- ESC [ r restores the scroll region to the full terminal.

The terminal hardware-accelerates the content shift. Only the newly revealed rows need to be painted by the application, which reduces both CPU work and visual tearing.

Utility Functions

ts
import {
  setScrollRegion,
  resetScrollRegion,
  scrollUp,
  scrollDown,
  moveCursor,
  supportsScrollRegions,
} from "@silvery/term"
FunctionDescription
setScrollRegion(stdout, top, bottom)Set DECSTBM region (1-indexed rows)
resetScrollRegion(stdout)Reset to full terminal
scrollUp(stdout, lines?)Scroll content up (default: 1 line)
scrollDown(stdout, lines?)Scroll content down (default: 1 line)
moveCursor(stdout, row, col)Move cursor to position (1-indexed)
supportsScrollRegions()Auto-detect terminal support

useScrollRegion Hook

ts
import { useScrollRegion } from "@silvery/term/hooks"

Tracks scroll offset changes and emits DECSTBM sequences automatically. Returns the scroll delta so the renderer knows which rows to repaint.

tsx
function ScrollableArea({ items, scrollOffset }) {
  const { isActive, scrollDelta } = useScrollRegion({
    top: 2, // 0-indexed screen row
    bottom: 20, // 0-indexed screen row
    scrollOffset,
    // enabled: true  // default: auto-detect
  })

  // scrollDelta tells you how many rows shifted:
  //   > 0 = scrolled down (new rows at bottom)
  //   < 0 = scrolled up (new rows at top)
  //   0   = no scroll (full repaint)
  return <VirtualList items={items} />
}

Options

OptionTypeDefaultDescription
topnumber--Top row (0-indexed)
bottomnumber--Bottom row (0-indexed)
scrollOffsetnumber--Current scroll position
enabledbooleanauto-detectForce on/off
stdoutNodeJS.WriteStreamprocess.stdoutOutput stream

Return Value

FieldTypeDescription
isActivebooleanWhether scroll region optimization is active
scrollDeltanumberLines shifted since last render

Terminal Compatibility

DECSTBM is widely supported by modern terminals:

TerminalSupported
GhosttyYes
iTerm2Yes
KittyYes
WezTermYes
xtermYes
tmuxYes
screenYes
VS CodeYes
Linux ttyNo

supportsScrollRegions() checks TERM_PROGRAM and TERM environment variables to auto-detect support. Override with the enabled option when you know the target environment.

Released under the MIT License.