Usage Guide

Learn how to use @visulima/ansi with practical examples

Last updated:

Usage Guide

Learn how to use ANSI escape codes to control your terminal output.

Cursor Control

Position Cursor

Move the cursor to specific coordinates:

import { cursorTo } from "@visulima/ansi";

// Move to column 10, row 5
process.stdout.write(cursorTo(10, 5));
console.log("Text at position (10, 5)");

// Move to column 0 (start of line)
process.stdout.write(cursorTo(0));
console.log("Back to line start");

Move Cursor Relative

Move cursor relative to current position:

import { cursorUp, cursorDown, cursorForward, cursorBackward } from "@visulima/ansi";

// Move up 3 lines
process.stdout.write(cursorUp(3));

// Move down 2 lines
process.stdout.write(cursorDown(2));

// Move forward 5 columns
process.stdout.write(cursorForward(5));

// Move backward 3 columns
process.stdout.write(cursorBackward(3));

Convenience shortcuts for single movements:

import { cursorLeft, CURSOR_UP_1, CURSOR_DOWN_1 } from "@visulima/ansi";

// Move left to column 0
process.stdout.write(cursorLeft);

// Move up one line
process.stdout.write(CURSOR_UP_1);

// Move down one line
process.stdout.write(CURSOR_DOWN_1);

Save and Restore Cursor

Save cursor position and restore later:

import { cursorSave, cursorRestore, cursorTo } from "@visulima/ansi";

// Save current position
process.stdout.write(cursorSave);

// Move somewhere else
process.stdout.write(cursorTo(20, 10));
console.log("Temporary text");

// Restore original position
process.stdout.write(cursorRestore);
console.log("Back to saved position");

Show and Hide Cursor

Control cursor visibility:

import { cursorHide, cursorShow } from "@visulima/ansi";

// Hide cursor during operation
process.stdout.write(cursorHide);

// Do work...
console.log("Processing...");
await someLongOperation();

// Show cursor again
process.stdout.write(cursorShow);

Style Cursor

Change cursor appearance:

import { setCursorStyle } from "@visulima/ansi";

// Blinking block cursor
process.stdout.write(setCursorStyle("blinking-block"));

// Steady underline cursor
process.stdout.write(setCursorStyle("steady-underline"));

// Blinking bar cursor
process.stdout.write(setCursorStyle("blinking-bar"));

Screen Manipulation

Clear Screen

Clear the entire screen or parts of it:

import { clearScreen, eraseDown, eraseUp } from "@visulima/ansi";

// Clear entire screen
process.stdout.write(clearScreen);

// Clear from cursor to end of screen
process.stdout.write(eraseDown);

// Clear from cursor to top of screen
process.stdout.write(eraseUp);

Clear and move cursor home:

import { clearScreenAndHomeCursor, clearScreenFromTopLeft } from "@visulima/ansi";

// Clear and move to (0, 0)
process.stdout.write(clearScreenAndHomeCursor);

// Clear from top-left
process.stdout.write(clearScreenFromTopLeft);

Clear Lines

Erase lines or parts of lines:

import { eraseLine, eraseLineEnd, eraseLineStart } from "@visulima/ansi";

// Erase entire current line
process.stdout.write(eraseLine);

// Erase from cursor to end of line
process.stdout.write(eraseLineEnd);

// Erase from cursor to start of line
process.stdout.write(eraseLineStart);

Erase multiple lines:

import { eraseLines } from "@visulima/ansi";

// Erase 3 lines
process.stdout.write(eraseLines(3));

Alternative Screen

Use alternative screen buffer (like vim/less):

import { alternativeScreenOn, alternativeScreenOff } from "@visulima/ansi";

// Switch to alternative screen
process.stdout.write(alternativeScreenOn);

// Your full-screen app here
console.log("Full-screen interface");

// Switch back to normal screen
process.stdout.write(alternativeScreenOff);

Scrolling

Scroll screen regions:

import { scrollUp, scrollDown } from "@visulima/ansi";

// Scroll up 5 lines
process.stdout.write(scrollUp(5));

// Scroll down 3 lines
process.stdout.write(scrollDown(3));

Make terminal output clickable:

import { hyperlink } from "@visulima/ansi";

const link = hyperlink("https://github.com/visulima", "Visulima on GitHub");
console.log(`Check out ${link} for more info!`);

With IDs for duplicate links:

import { hyperlink } from "@visulima/ansi";

const link1 = hyperlink("https://example.com", "Example 1", { id: "link-1" });
const link2 = hyperlink("https://example.com", "Example 2", { id: "link-2" });

console.log(link1);
console.log(link2);

Images (iTerm2)

Display Images

Show images in iTerm2:

import { image } from "@visulima/ansi";
import { readFileSync } from "fs";

const imageData = readFileSync("logo.png");

// Display image
process.stdout.write(image(imageData, {
  width: "50%",
  height: "auto",
  preserveAspectRatio: true
}));

Inline images:

import { image } from "@visulima/ansi";
import { readFileSync } from "fs";

const icon = readFileSync("icon.png");

// Display inline with text
process.stdout.write(`Status: ${image(icon, { width: 20, height: 20, inline: true })} Complete`);

Strip ANSI Codes

Remove ANSI from Strings

Clean ANSI codes for logging or storage:

import { strip } from "@visulima/ansi";
import { cursorUp, clearScreen } from "@visulima/ansi";

const withAnsi = `${clearScreen}Hello${cursorUp(2)} World`;
const cleaned = strip(withAnsi);

console.log(cleaned); // "Hello World" (no ANSI codes)

Useful for measuring actual text length:

import { strip } from "@visulima/ansi";
import { hyperlink } from "@visulima/ansi";

const link = hyperlink("https://example.com", "Example");
const textOnly = strip(link);

console.log(link.length);      // Long (includes ANSI codes)
console.log(textOnly.length);  // 7 (just "Example")

Window Control

Set Window Title

Change terminal window title:

import { setWindowTitle, setIconName } from "@visulima/ansi";

// Set window title
process.stdout.write(setWindowTitle("My CLI App"));

// Set icon name
process.stdout.write(setIconName("CLI"));

Set both at once:

import { setIconNameAndWindowTitle } from "@visulima/ansi";

process.stdout.write(setIconNameAndWindowTitle("CLI App"));

Window Operations

Control window state (terminal support varies):

import {
  minimizeWindow,
  maximizeWindow,
  raiseWindow,
  lowerWindow
} from "@visulima/ansi";

// Minimize window
process.stdout.write(minimizeWindow);

// Maximize window
process.stdout.write(maximizeWindow);

// Bring window to front
process.stdout.write(raiseWindow);

// Send window to back
process.stdout.write(lowerWindow);

Move and resize window:

import { moveWindow, resizeTextAreaChars } from "@visulima/ansi";

// Move window to position (100, 100)
process.stdout.write(moveWindow(100, 100));

// Resize to 80 columns, 24 rows
process.stdout.write(resizeTextAreaChars(80, 24));

Mouse Events

Enable Mouse Tracking

Track mouse events in terminal:

import { enableNormalMouse, disableNormalMouse } from "@visulima/ansi";
import { stdin } from "process";

// Enable mouse tracking
process.stdout.write(enableNormalMouse);

// Listen for mouse events
stdin.setRawMode(true);
stdin.on("data", (data) => {
  // Parse mouse event from data
  console.log("Mouse event:", data);
});

// Disable when done
process.on("exit", () => {
  process.stdout.write(disableNormalMouse);
  stdin.setRawMode(false);
});

Different mouse modes:

import {
  enableButtonEventMouse,
  enableAnyEventMouse,
  enableX10Mouse
} from "@visulima/ansi";

// Track button presses and releases
process.stdout.write(enableButtonEventMouse);

// Track all mouse movement
process.stdout.write(enableAnyEventMouse);

// Simple X10 mouse protocol
process.stdout.write(enableX10Mouse);

Terminal Modes

Control Terminal Behavior

Enable and disable terminal modes:

import { setMode, resetMode } from "@visulima/ansi";

// Enable insert mode
process.stdout.write(setMode("IRM"));

// Disable insert mode
process.stdout.write(resetMode("IRM"));

Common modes:

import {
  SetLineFeedNewLineMode,
  ResetLineFeedNewLineMode
} from "@visulima/ansi";

// Enable line feed/new line mode
process.stdout.write(SetLineFeedNewLineMode);

// Disable it
process.stdout.write(ResetLineFeedNewLineMode);

Real-World Examples

Progress Bar

Create an updating progress bar:

import {
  cursorHide,
  cursorShow,
  cursorTo,
  eraseLine
} from "@visulima/ansi";

function showProgress(current: number, total: number) {
  const percent = Math.floor((current / total) * 100);
  const filled = Math.floor(percent / 2);
  const bar = "█".repeat(filled) + "░".repeat(50 - filled);

  process.stdout.write(cursorHide);
  process.stdout.write(cursorTo(0));
  process.stdout.write(eraseLine);
  process.stdout.write(`Progress: [${bar}] ${percent}%`);

  if (current === total) {
    process.stdout.write("\n");
    process.stdout.write(cursorShow);
  }
}

// Use it
for (let i = 0; i <= 100; i++) {
  showProgress(i, 100);
  await new Promise(resolve => setTimeout(resolve, 50));
}

Spinner Animation

Create a loading spinner:

import { cursorHide, cursorShow, cursorBackward, eraseLine } from "@visulima/ansi";

const frames = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];

async function spinner(message: string, duration: number) {
  process.stdout.write(cursorHide);

  let frame = 0;
  const interval = setInterval(() => {
    process.stdout.write(cursorBackward(100));
    process.stdout.write(eraseLine);
    process.stdout.write(`${frames[frame]} ${message}`);
    frame = (frame + 1) % frames.length;
  }, 80);

  await new Promise(resolve => setTimeout(resolve, duration));

  clearInterval(interval);
  process.stdout.write(cursorBackward(100));
  process.stdout.write(eraseLine);
  process.stdout.write(cursorShow);
}

// Use it
await spinner("Loading...", 3000);
console.log("✓ Complete!");

Interactive Menu

Build a simple menu with cursor control:

import {
  cursorHide,
  cursorShow,
  cursorUp,
  cursorTo,
  eraseLine
} from "@visulima/ansi";

const options = ["Option 1", "Option 2", "Option 3", "Exit"];
let selected = 0;

function drawMenu() {
  console.log("\nSelect an option:");
  options.forEach((option, index) => {
    const prefix = index === selected ? ">" : " ";
    console.log(`${prefix} ${option}`);
  });
}

function updateMenu() {
  process.stdout.write(cursorUp(options.length + 1));
  process.stdout.write(cursorTo(0));

  options.forEach((option, index) => {
    process.stdout.write(eraseLine);
    const prefix = index === selected ? ">" : " ";
    console.log(`${prefix} ${option}`);
  });
}

// Initial draw
drawMenu();

// Handle keyboard input
process.stdin.setRawMode(true);
process.stdin.on("data", (data) => {
  const key = data.toString();

  if (key === "\u001b[A") { // Up arrow
    selected = Math.max(0, selected - 1);
    updateMenu();
  } else if (key === "\u001b[B") { // Down arrow
    selected = Math.min(options.length - 1, selected + 1);
    updateMenu();
  } else if (key === "\r") { // Enter
    console.log(`\nYou selected: ${options[selected]}`);
    process.exit(0);
  } else if (key === "\u0003") { // Ctrl+C
    process.exit(0);
  }
});

Full-Screen App

Create a full-screen terminal application:

import {
  alternativeScreenOn,
  alternativeScreenOff,
  clearScreen,
  cursorTo,
  cursorHide,
  cursorShow
} from "@visulima/ansi";

async function fullScreenApp() {
  // Enter alternative screen
  process.stdout.write(alternativeScreenOn);
  process.stdout.write(clearScreen);
  process.stdout.write(cursorHide);

  // Draw UI
  process.stdout.write(cursorTo(0, 0));
  console.log("┌────────────────────────────┐");
  console.log("│   My Full-Screen App       │");
  console.log("└────────────────────────────┘");

  // Wait for input
  await new Promise(resolve => {
    process.stdin.setRawMode(true);
    process.stdin.once("data", resolve);
  });

  // Clean up
  process.stdout.write(cursorShow);
  process.stdout.write(alternativeScreenOff);
  process.stdin.setRawMode(false);
}

// Run it
await fullScreenApp();

Status Updates

Update status line without scrolling:

import { cursorSave, cursorRestore, cursorTo, eraseLine } from "@visulima/ansi";

let statusLine = 0;

function setStatus(message: string) {
  process.stdout.write(cursorSave);
  process.stdout.write(cursorTo(0, statusLine));
  process.stdout.write(eraseLine);
  process.stdout.write(`Status: ${message}`);
  process.stdout.write(cursorRestore);
}

// Use it
console.log("Starting process...");
statusLine = 1;

setStatus("Initializing...");
await delay(1000);

console.log("Doing work...");

setStatus("Processing...");
await delay(2000);

setStatus("Complete!");

Next Steps

API Reference

Complete API documentation for all functions

Back to Overview

Return to package overview

Support

Contribute to our work and keep us going

Community is the heart of open source. The success of our packages wouldn't be possible without the incredible contributions of users, testers, and developers who collaborate with us every day.Want to get involved? Here are some tips on how you can make a meaningful impact on our open source projects.

Ready to help us out?

Be sure to check out the package's contribution guidelines first. They'll walk you through the process on how to properly submit an issue or pull request to our repositories.

Submit a pull request

Found something to improve? Fork the repo, make your changes, and open a PR. We review every contribution and provide feedback to help you get merged.

Good first issues

Simple issues suited for people new to open source development, and often a good place to start working on a package.
View good first issues