# ansi-escapes: named terminal control sequences for Node and the browser

> ansi-escapes is a small MIT licensed module that returns ANSI escape sequences as strings, covering cursor movement, erasing, the alternative screen, synchronized output, hyperlinks, images and a few terminal specific extras. It fits code that drives a terminal from JavaScript, and it does not fit a program that needs to know which terminal it is talking to before it emits the sequence.

**sindresorhus/ansi-escapes** — ANSI escape codes for manipulating the terminal

- Repository: https://github.com/sindresorhus/ansi-escapes
- Stars: 553 · Forks: 53
- Language: JavaScript
- License: MIT
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/sindresorhus-ansi-escapes

## Named functions instead of literal escape sequences

ansi-escapes is described as ANSI escape codes for manipulating the terminal, and the value it adds over writing the bytes yourself is naming. A function called cursorUp or eraseEndLine documents its own effect, whereas the literal sequence does not. The module is a single JavaScript file with a TypeScript declaration file next to it, published under the MIT licence, and it is a dependency of the kind of thing a CLI author adds without thinking about it. The audience is anyone writing a command line tool in JavaScript, a progress indicator, a spinner, a live-updating status line, or a browser based terminal emulator that has to move the cursor and erase parts of the screen. The scope is deliberately narrow. It does not style text, it does not draw boxes, and it does not measure terminal width.

## Cursor movement in absolute and relative terms

The API is grouped by what it touches. The cursor group is the largest. cursorTo sets the absolute position of the cursor, where x0 y0 is the top left of the screen, and cursorMove sets the position relative to the current position, which is the one most tools want since it survives text already on screen. The counted moves are cursorUp, cursorDown, cursorForward and cursorBackward, each taking a count with a default of 1, and the README's usage example composes them: moving two rows up and to the left is written as a cursorUp call with an argument of 2 concatenated with the cursorLeft constant, since that one has no count and moves to the left side. There is also cursorNextLine and cursorPrevLine to jump a line while keeping the column, cursorSavePosition and cursorRestorePosition to park the cursor and come back to it, and cursorGetPosition to ask where it is. cursorHide and cursorShow round out the group, and those two matter for any tool that wants a clean line of output while it works.

## Erasing lines and the risk in clearScreen

The erasing group covers the screen in slices. eraseLines erases from the current cursor position up the specified amount of rows, eraseEndLine erases from the cursor to the end of the current line, eraseStartLine erases from the cursor to the start of the current line, eraseLine erases the entire current line, eraseDown erases from the current line down to the bottom of the screen, and eraseUp erases from the current line up to the top. Then the three full clears, and this is where the documentation gets serious. clearScreen uses RIS, Reset to Initial State, and the README carries a warning that this may also clear the scrollback buffer in some terminals, naming xterm.js and VTE, and that it resets terminal modes. The recommended alternative is clearViewport, which clears only the visible terminal screen without affecting the scrollback buffer or the terminal state, and which the README calls a safer alternative that works consistently across terminals. clearTerminal is the third option and it clears the whole terminal including the scrollback buffer, not just the visible part. A spinner that calls clearScreen will quietly destroy a user's scrollback in some terminals.

## The alternative screen and synchronized output for flicker

Two features target programs that redraw a lot. The alternative screen buffer is a second screen the terminal switches to, and the module exposes enterAlternativeScreen and exitAlternativeScreen, the latter assuming the former was called before. That is how a full screen program such as a pager or an editor keeps the user's scrollback intact: it draws into a buffer that is thrown away on exit. The other feature is synchronized output, which the README describes as reducing flicker during renders. There are three entry points: beginSynchronizedOutput and endSynchronizedOutput to bracket a render manually, and synchronizedOutput, which takes text and wraps it in the synchronized output sequences for you. The value of synchronized output is that a terminal that supports the extension can paint a whole frame in one go instead of showing a half-drawn screen, which is exactly the symptom of a progress bar or a live table redrawing too fast for the terminal to keep up.

## Terminal specific extras for iTerm2, ConEmu and hyperlinks

A group of functions reaches beyond the portable core, and this is where a caller has to make a decision. setCwd sets the current working directory for both iTerm2 and ConEmu, and it is the working directory that the terminal is told about, with the default being process.cwd(). There is a separate iTerm.setCwd, which informs iTerm2 of the current directory to help semantic history and enable Cmd-clicking relative paths, and a ConEmu.setCwd, which informs ConEmu about the shell's working directory. The iTerm.annotation function creates an escape code to display an annotation in iTerm2, and it takes a message plus options for length, x, y and isHidden, with the note that the pipe character is disallowed in the message and will be stripped, and that x and y must be used with length. The link function creates a clickable link, and the README links a list of supported terminals and points at the separate supports-hyperlinks package to detect link support. The image function displays an image from a Buffer, with width and height given as a number with a unit or the word auto, where the units are character cells, pixels or a percentage of the session, and the README points at term-img as a higher level module for that job.

## Using it from Node and from Xterm.js in the browser

Installation is a single npm command, and the package is published under the name ansi-escapes:

```sh
npm install ansi-escapes
```

In Node the default export gives an object of functions and constants, and the usage example writes a cursor movement straight to standard output:

```js
import ansiEscapes from 'ansi-escapes';

// Moves the cursor two rows up and to the left
process.stdout.write(ansiEscapes.cursorUp(2) + ansiEscapes.cursorLeft);
//=> '\u001B[2A\u001B[1000D'
```

If the named exports suit your style better, the README shows the same functions imported by name, and the default export is the one to reach for when the module is used as an object. The browser case is the same module writing into an Xterm.js terminal, where the write call goes to the terminal object rather than to process.stdout:

```js
import ansiEscapes from 'ansi-escapes';
import {Terminal} from 'xterm';
import 'xterm/css/xterm.css';

const terminal = new Terminal({…});

// Moves the cursor two rows up and to the left
terminal.write(ansiEscapes.cursorUp(2) + ansiEscapes.cursorLeft);
//=> '\u001B[2A\u001B[1000D'
```

The important detail is that the escape sequences are the same in both places, so a rendering routine written for a terminal can be reused in a browser based emulator without a second implementation of the drawing logic.

## An ESM only module with one small runtime dependency

The package.json shows the shape of the module and the constraints on using it. It is an ES module, with type set to module and an exports map that points types at index.d.ts and default at index.js, so a CommonJS project cannot require it directly. The engines field requires Node 18 or newer. It has one runtime dependency, the environment package, and it declares sideEffects as false, which tells a bundler it can drop the import if nothing from it is used. The published files list is only four entries: index.js, index.d.ts, base.js and base.d.ts, so the split between base and index is the difference between the escape sequences themselves and the higher level functions built on them. Types are shipped and tested with tsd, and the test script runs ava together with tsd. The licence file is MIT. The README also names a sibling project, ansi-styles, which covers ANSI escape codes for styling strings, so the two modules are complements rather than competitors.

## Release history and what a major version tends to mean here

The project is not archived and the last push was on 2026-09-18. The visible releases are v7.3.0 on 2026-02-04, v7.2.0 on 2025-11-04 and v7.1.1 on 2025-09-23, and the current version in package.json matches the latest tag. The release record shows a steady patch cadence inside a major version, which for a module of this kind usually means new terminal capabilities and new function names rather than changes to the ones you already use. The clearViewport and synchronizedOutput entries are examples of that pattern, since both address problems that appear only on terminals with particular extension support. The practical upgrade advice is narrow: read the changelog entry for a major version before bumping it, because a module that adds functions is easy to adopt but a module that renames or changes the meaning of an existing constant, such as the clearing functions, is not.

## Conclusion

ansi-escapes fits a Node or browser program that writes to a terminal or to Xterm.js and wants readable code instead of literal escape strings, and it is a reasonable dependency to take for a single utility. It does not fit a program that must degrade gracefully on a terminal without a given capability, since the README offers a separate detection package for hyperlinks rather than a built-in check. Verify first which of the three clearing functions you actually want, because the README warns that clearScreen uses RIS, which may also clear the scrollback buffer in xterm.js and VTE, and clearViewport is the safer choice.

## FAQ

### How do I install ansi-escapes and move the cursor?

Install it with npm install ansi-escapes, then import the default export and write to process.stdout. The README example moves the cursor two rows up and to the left with process.stdout.write(ansiEscapes.cursorUp(2) + ansiEscapes.cursorLeft).

### What is the difference between clearScreen, clearViewport and clearTerminal?

clearScreen uses RIS, Reset to Initial State, and the README warns it may also clear the scrollback buffer in some terminals such as xterm.js and VTE and resets terminal modes. clearViewport clears only the visible screen without touching the scrollback or terminal state, and clearTerminal clears the whole terminal including the scrollback buffer.

### Does ansi-escapes work in the browser with Xterm.js?

Yes. The README shows the same escape sequences written into an Xterm.js Terminal object with terminal.write(ansiEscapes.cursorUp(2) + ansiEscapes.cursorLeft), so a rendering routine can be shared between Node and the browser.

### Can ansi-escapes create hyperlinks and display images?

The link function creates a clickable link, with the README linking a list of supported terminals and pointing at the separate supports-hyperlinks package for detection. The image function displays an image from a Buffer, and the README points at term-img as a higher level module for that.

## Sources

- [Issues](https://github.com/sindresorhus/ansi-escapes/issues)
- [License: MIT](https://github.com/sindresorhus/ansi-escapes/blob/main/LICENSE)
- [README](https://github.com/sindresorhus/ansi-escapes/blob/main/README.md)
- [Releases](https://github.com/sindresorhus/ansi-escapes/releases)
- [sindresorhus/ansi-escapes on GitHub](https://github.com/sindresorhus/ansi-escapes)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/sindresorhus-ansi-escapes
