Description
This issue tracks the migration from the ansi-colors package to Node.js's built-in util.styleText API. The goal is to reduce external dependencies by leveraging Node.js's native terminal styling capabilities.
Unlike other color libraries (like kleur), ansi-colors applies its multi-style stacks in reverse order, which exactly matches how util.styleText evaluates arrays of styles. As a result, all compatible chains produce a byte-for-byte exact ANSI escape code match.
Migration Scope
Compatible Features:
- Basic colors (
black, red, green, yellow, blue, magenta, cyan, white)
- Gray / Grey Aliases (
gray and grey map seamlessly to blackBright)
- Bright variants (
redBright, greenBright, yellowBright, etc.)
- Background colors (
bgRed, bgGreen, etc.) and Bright Backgrounds (bgRedBright, etc.)
- Text modifiers (
reset, bold, dim, italic, underline, inverse, hidden, strikethrough)
- Property Chaining via nested property access (e.g.,
ac.bold.red('text') converts to an ordered array styleText(['bold', 'red'], 'text'))
- Inline String Concatenation & Template Literals
Non-Compatible Features (Requires Skipping + Manual Intervention Warnings):
- Runtime Toggles:
ac.enabled = false and conditional flag disabling.
- Output Suppression:
ac.visible = false (which silently returns an empty string '').
- Utility Methods:
ac.unstyle(), ac.stripColor(), ac.hasAnsi(), and ac.hasColor().
- Theme & Alias Registry:
ac.alias() and ac.theme().
- Factories & Custom Codes:
ac.create() and ac.define().
- Passthroughs & Symbols:
ac.noop, ac.none, ac.clear, and the cross-platform unicode symbol map ac.symbols.
Benefits
- Zero Dependencies: Eliminates the need for the external
ansi-colors package.
- No Performance Trade-offs: Retains identical byte-for-byte output since both tools stack styles in reverse sequence.
- Native Support: Standardizes terminal behavior using built-in Node.js platform APIs (v20.12+ / v21.7+).
Examples
The following suite of examples demonstrates how the codemod must transform code patterns based on the verified validation rules.
Case 1: Basic Color & Alias Usage
Before:
const ac = require('ansi-colors');
console.log(ac.red('Error message'));
console.log(ac.gray('Hint text'));
After:
const { styleText } = require('node:util');
console.log(styleText('red', 'Error message'));
console.log(styleText('gray', 'Hint text'));
Case 2: Multi-Style Property Chaining (Reverse Order Resolution)
Before:
import ac from 'ansi-colors';
// Property access chaining (not method execution)
console.log(ac.bold.red('Critical failure'));
console.log(ac.bgBlue.white.bold('HEADER TEXT'));
After:
import { styleText } from 'node:util';
console.log(styleText(['bold', 'red'], 'Critical failure'));
console.log(styleText(['bgBlue', 'white', 'bold'], 'HEADER TEXT'));
Case 3: Template Literals with Deeply Chained Badges
Before:
const ac = require('ansi-colors');
const file = 'server.js';
const line = '42';
console.log(`${ac.bold.red("[ERR]")} ${ac.dim(file)}:${ac.dim(line)}`);
console.log(`Multi-badge: ${ac.bgRed.white(" ERR ")} ${ac.bgGreen.black(" OK ")}`);
After:
const { styleText } = require('node:util');
const file = 'server.js';
const line = '42';
console.log(`${styleText(['bold', 'red'], '[ERR]')} ${styleText('dim', file)}:${styleText('dim', line)}`);
console.log(`Multi-badge: ${styleText(['bgRed', 'white'], ' ERR ')} ${styleText(['bgGreen', 'black'], ' OK ')}`);
Case 4: String Concatenation Contexts
Before:
const ac = require('ansi-colors');
console.log('Hello, ' + ac.green('World') + '!');
console.log(ac.bgRedBright.white(' ERR ') + ' ' + ac.red('File not found'));
After:
const { styleText } = require('node:util');
console.log('Hello, ' + styleText('green', 'World') + '!');
console.log(styleText(['bgRedBright', 'white'], ' ERR ') + ' ' + styleText('red', 'File not found'));
Case 5: Reusable Style Functions and Conditionals
Before:
const ac = require('ansi-colors');
const errorStyle = (msg) => ac.bold.red(msg);
const status = level === 'error' ? ac.bold.red('boom') : ac.yellow('slow');
After:
const { styleText } = require('node:util');
const errorStyle = (msg) => styleText(['bold', 'red'], msg);
const status = level === 'error' ? styleText(['bold', 'red'], 'boom') : styleText('yellow', 'slow');
Non-Migratable Warnings & Adjustments
When the codemod detects un-migratable APIs, it must skip transformation for that block and output a structured console notification advising manual remediation:
- **For
ac.enabled = false**:
Warning: util.styleText has no equivalent runtime instance flag. Map this configuration to environment variables instead: set process.env.NO_COLOR='1' or NODE_DISABLE_COLORS='1' before application initialization.
- **For
ac.visible = false**:
Warning: util.styleText lacks a visual toggling mechanism and will always return a string wrapper. Please guard the call site explicitly: const out = visible ? styleText('red', msg) : '';.
- **For
ac.unstyle(str) / ac.stripColor(str)**:
Warning: util.styleText does not expose an ANSI text stripper. Replace with a native regex str.replace(/\x1b\[[0-9;]*m/g, '') or install a zero-dependency package like strip-ansi.
- For Custom Themes / Aliases (
ac.theme, ac.alias, ac.define):
Warning: util.styleText is stateless and does not maintain a style or theme registry. Migrate global configurations to dedicated structural objects mapping keys to arrow functions (e.g., const theme = { error: (m) => styleText(['bold', 'red'], m) }).
Additional Note
https://github.com/nodejs/userland-migrations/blob/main/utils/src/ast-grep/package-json.ts may need to be extended to fully support dependency cleanup post-migration.
REFS
Description
This issue tracks the migration from the ansi-colors package to Node.js's built-in util.styleText API. The goal is to reduce external dependencies by leveraging Node.js's native terminal styling capabilities.
Unlike other color libraries (like kleur), ansi-colors applies its multi-style stacks in reverse order, which exactly matches how util.styleText evaluates arrays of styles. As a result, all compatible chains produce a byte-for-byte exact ANSI escape code match.
Migration Scope
Compatible Features:
- Basic colors (
black, red, green, yellow, blue, magenta, cyan, white)
- Gray / Grey Aliases (
gray and grey map seamlessly to blackBright)
- Bright variants (
redBright, greenBright, yellowBright, etc.)
- Background colors (
bgRed, bgGreen, etc.) and Bright Backgrounds (bgRedBright, etc.)
- Text modifiers (
reset, bold, dim, italic, underline, inverse, hidden, strikethrough)
- Property Chaining via nested property access (e.g.,
ac.bold.red('text') converts to an ordered array styleText(['bold', 'red'], 'text'))
- Inline String Concatenation & Template Literals
Non-Compatible Features (Requires Skipping + Manual Intervention Warnings):
- Runtime Toggles:
ac.enabled = false and conditional flag disabling.
- Output Suppression:
ac.visible = false (which silently returns an empty string '').
- Utility Methods:
ac.unstyle(), ac.stripColor(), ac.hasAnsi(), and ac.hasColor().
- Theme & Alias Registry:
ac.alias() and ac.theme().
- Factories & Custom Codes:
ac.create() and ac.define().
- Passthroughs & Symbols:
ac.noop, ac.none, ac.clear, and the cross-platform unicode symbol map ac.symbols.
Benefits
- Zero Dependencies: Eliminates the need for the external
ansi-colors package.
- No Performance Trade-offs: Retains identical byte-for-byte output since both tools stack styles in reverse sequence.
- Native Support: Standardizes terminal behavior using built-in Node.js platform APIs (v20.12+ / v21.7+).
Examples
The following suite of examples demonstrates how the codemod must transform code patterns based on the verified validation rules.
Case 1: Basic Color & Alias Usage
Before:
const ac = require('ansi-colors');
console.log(ac.red('Error message'));
console.log(ac.gray('Hint text'));
After:
const { styleText } = require('node:util');
console.log(styleText('red', 'Error message'));
console.log(styleText('gray', 'Hint text'));
Case 2: Multi-Style Property Chaining (Reverse Order Resolution)
Before:
import ac from 'ansi-colors';
// Property access chaining (not method execution)
console.log(ac.bold.red('Critical failure'));
console.log(ac.bgBlue.white.bold('HEADER TEXT'));
After:
import { styleText } from 'node:util';
console.log(styleText(['bold', 'red'], 'Critical failure'));
console.log(styleText(['bgBlue', 'white', 'bold'], 'HEADER TEXT'));
Case 3: Template Literals with Deeply Chained Badges
Before:
const ac = require('ansi-colors');
const file = 'server.js';
const line = '42';
console.log(`${ac.bold.red("[ERR]")} ${ac.dim(file)}:${ac.dim(line)}`);
console.log(`Multi-badge: ${ac.bgRed.white(" ERR ")} ${ac.bgGreen.black(" OK ")}`);
After:
const { styleText } = require('node:util');
const file = 'server.js';
const line = '42';
console.log(`${styleText(['bold', 'red'], '[ERR]')} ${styleText('dim', file)}:${styleText('dim', line)}`);
console.log(`Multi-badge: ${styleText(['bgRed', 'white'], ' ERR ')} ${styleText(['bgGreen', 'black'], ' OK ')}`);
Case 4: String Concatenation Contexts
Before:
const ac = require('ansi-colors');
console.log('Hello, ' + ac.green('World') + '!');
console.log(ac.bgRedBright.white(' ERR ') + ' ' + ac.red('File not found'));
After:
const { styleText } = require('node:util');
console.log('Hello, ' + styleText('green', 'World') + '!');
console.log(styleText(['bgRedBright', 'white'], ' ERR ') + ' ' + styleText('red', 'File not found'));
Case 5: Reusable Style Functions and Conditionals
Before:
const ac = require('ansi-colors');
const errorStyle = (msg) => ac.bold.red(msg);
const status = level === 'error' ? ac.bold.red('boom') : ac.yellow('slow');
After:
const { styleText } = require('node:util');
const errorStyle = (msg) => styleText(['bold', 'red'], msg);
const status = level === 'error' ? styleText(['bold', 'red'], 'boom') : styleText('yellow', 'slow');
Non-Migratable Warnings & Adjustments
When the codemod detects un-migratable APIs, it must skip transformation for that block and output a structured console notification advising manual remediation:
Warning: util.styleText has no equivalent runtime instance flag. Map this configuration to environment variables instead: set process.env.NO_COLOR='1' or NODE_DISABLE_COLORS='1' before application initialization.
Warning: util.styleText lacks a visual toggling mechanism and will always return a string wrapper. Please guard the call site explicitly: const out = visible ? styleText('red', msg) : '';.
- For
ac.unstyle(str) / ac.stripColor(str):
Warning: util.styleText does not expose an ANSI text stripper. Replace with a native regex str.replace(/\x1b\[[0-9;]*m/g, '') or install a zero-dependency package like strip-ansi.
- For Custom Themes / Aliases (
ac.theme, ac.alias, ac.define):
Warning: util.styleText is stateless and does not maintain a style or theme registry. Migrate global configurations to dedicated structural objects mapping keys to arrow functions (e.g., const theme = { error: (m) => styleText(['bold', 'red'], m) }).
Additional Note
https://github.com/nodejs/userland-migrations/blob/main/utils/src/ast-grep/package-json.ts may need to be extended to fully support dependency cleanup post-migration.
REFS
Description
This issue tracks the migration from the
ansi-colorspackage to Node.js's built-inutil.styleTextAPI. The goal is to reduce external dependencies by leveraging Node.js's native terminal styling capabilities.Unlike other color libraries (like
kleur),ansi-colorsapplies its multi-style stacks in reverse order, which exactly matches howutil.styleTextevaluates arrays of styles. As a result, all compatible chains produce a byte-for-byte exact ANSI escape code match.Migration Scope
Compatible Features:
black,red,green,yellow,blue,magenta,cyan,white)grayandgreymap seamlessly toblackBright)redBright,greenBright,yellowBright, etc.)bgRed,bgGreen, etc.) and Bright Backgrounds (bgRedBright, etc.)reset,bold,dim,italic,underline,inverse,hidden,strikethrough)ac.bold.red('text')converts to an ordered arraystyleText(['bold', 'red'], 'text'))Non-Compatible Features (Requires Skipping + Manual Intervention Warnings):
ac.enabled = falseand conditional flag disabling.ac.visible = false(which silently returns an empty string'').ac.unstyle(),ac.stripColor(),ac.hasAnsi(), andac.hasColor().ac.alias()andac.theme().ac.create()andac.define().ac.noop,ac.none,ac.clear, and the cross-platform unicode symbol mapac.symbols.Benefits
ansi-colorspackage.Examples
The following suite of examples demonstrates how the codemod must transform code patterns based on the verified validation rules.
Case 1: Basic Color & Alias Usage
Before:
After:
Case 2: Multi-Style Property Chaining (Reverse Order Resolution)
Before:
After:
Case 3: Template Literals with Deeply Chained Badges
Before:
After:
Case 4: String Concatenation Contexts
Before:
After:
Case 5: Reusable Style Functions and Conditionals
Before:
After:
Non-Migratable Warnings & Adjustments
When the codemod detects un-migratable APIs, it must skip transformation for that block and output a structured console notification advising manual remediation:
ac.enabled = false**:ac.visible = false**:ac.unstyle(str)/ac.stripColor(str)**:ac.theme,ac.alias,ac.define):Additional Note
https://github.com/nodejs/userland-migrations/blob/main/utils/src/ast-grep/package-json.ts may need to be extended to fully support dependency cleanup post-migration.
REFS
ansi-colorsto Node.js's built-inutil.styleTextAPI, meticulously compiled directly from your validation script.Description
This issue tracks the migration from the
ansi-colorspackage to Node.js's built-inutil.styleTextAPI. The goal is to reduce external dependencies by leveraging Node.js's native terminal styling capabilities.Unlike other color libraries (like
kleur),ansi-colorsapplies its multi-style stacks in reverse order, which exactly matches howutil.styleTextevaluates arrays of styles. As a result, all compatible chains produce a byte-for-byte exact ANSI escape code match.Migration Scope
Compatible Features:
black,red,green,yellow,blue,magenta,cyan,white)grayandgreymap seamlessly toblackBright)redBright,greenBright,yellowBright, etc.)bgRed,bgGreen, etc.) and Bright Backgrounds (bgRedBright, etc.)reset,bold,dim,italic,underline,inverse,hidden,strikethrough)ac.bold.red('text')converts to an ordered arraystyleText(['bold', 'red'], 'text'))Non-Compatible Features (Requires Skipping + Manual Intervention Warnings):
ac.enabled = falseand conditional flag disabling.ac.visible = false(which silently returns an empty string'').ac.unstyle(),ac.stripColor(),ac.hasAnsi(), andac.hasColor().ac.alias()andac.theme().ac.create()andac.define().ac.noop,ac.none,ac.clear, and the cross-platform unicode symbol mapac.symbols.Benefits
ansi-colorspackage.Examples
The following suite of examples demonstrates how the codemod must transform code patterns based on the verified validation rules.
Case 1: Basic Color & Alias Usage
Before:
After:
Case 2: Multi-Style Property Chaining (Reverse Order Resolution)
Before:
After:
Case 3: Template Literals with Deeply Chained Badges
Before:
After:
Case 4: String Concatenation Contexts
Before:
After:
Case 5: Reusable Style Functions and Conditionals
Before:
After:
Non-Migratable Warnings & Adjustments
When the codemod detects un-migratable APIs, it must skip transformation for that block and output a structured console notification advising manual remediation:
ac.enabled = false:ac.visible = false:ac.unstyle(str)/ac.stripColor(str):ac.theme,ac.alias,ac.define):Additional Note
https://github.com/nodejs/userland-migrations/blob/main/utils/src/ast-grep/package-json.ts may need to be extended to fully support dependency cleanup post-migration.
REFS