ansis

repository·master·Indexed 19 days ago

https://github.com/webdiscus/ansis

A high-performance, lightweight ANSI color library for terminals, CI environments, and Chromium-based browsers. Version 4.3.1 supports Truecolor (Hex/RGB), 256 colors, and 16 basic colors with automatic fallback. It features a developer-friendly syntax using template literals and chaining, supports nested templates, and provides robust handling for new lines and non-string arguments. Compatible with Node.js v14+, Deno v2.0+, and various modern build tools.

Tokens
11K
Snippets
48
Records
57
Agent score
65%

What's inside ansis

  1. Performance comparison: Chained vs Nested syntax

    master

    When comparing performance between libraries, it is important to use the fastest styling method supported by the library.

    • Chained syntax (e.g., lib.red.bold('text')) is faster and more concise.
    • Nested syntax (e.g., lib.red(lib.bold('text'))) is slower and more verbose.

    ansis and chalk support chained syntax, whereas libraries like picocolors, colorette, and kleur do not and require nested calls.

    // Fast and short (Chained)
    lib.red.bold.bgWhite(' ERROR ')
    
    // Slower and verbose (Nested)
    lib.red(lib.bold(lib.bgWhite(' ERROR ')))
  2. Understand color naming conventions in ansis

    master

    When choosing between different ANSI color libraries, be aware that naming conventions for specific colors vary.

    ansis uses the standard American spelling gray and bgGray (for ANSI code 90 and 100 respectively). Unlike some other libraries, ansis avoids redundant aliases, meaning it does not provide the UK spelling grey or bgGrey, nor does it use the spec-style blackBright or bgBlackBright names for these specific codes.

    If you are migrating from a library like chalk or colors.js, ensure you update your code to use gray instead of grey or blackBright to maintain compatibility with ansis.

  3. How ansis handles line feeds (\n)

    master

    The ansis library ensures that ANSI styles are correctly applied even when strings contain line feed characters (\n). This prevents styles from 'leaking' or breaking incorrectly at the end of a line.

    console.log(bgGreen('\nAnsis\nNew Line\nNext New Line\n'))
  4. Understand Ansis color fallback behavior

    master

    Ansis features smart auto-detection and automatic fallback. If a terminal does not support a specific color depth, Ansis will downgrade the colors to the next best available level to ensure visibility:

    Truecolor $\rightarrow$ 256 colors $\rightarrow$ 16 colors $\rightarrow$ no colors (b&w)

  5. How ansis handles color fallbacks

    master

    The ansis library implements a progressive fallback mechanism to ensure color output works across different terminal capabilities. The fallback order is:

    1. Truecolor (16m colors)
    2. 256 colors
    3. 16 colors (ANSI 16)
    4. No colors (Black & White)
  6. How color auto-detection works

    master

    Ansis determines color support by inspecting the runtime environment in a specific priority order:

    1. Chromium-like runtimes: Detected first, defaults to truecolor.
    2. COLORTERM environment variable:
      • truecolor or 24bit $\rightarrow$ truecolor
      • ansi256 $\rightarrow$ 256 colors
      • ansi $\rightarrow$ 16 colors
    3. CI environments:
      • GitHub Actions $\rightarrow$ truecolor
      • Other CI $\rightarrow$ 16 colors
    4. Terminal TTY status:
      • No TTY or TERM=dumb $\rightarrow$ no colors.
      • PM2 and Next.js non-TTY runtimes $\rightarrow$ color output.
    5. Windows: Windows 10 (build 14931+) $\rightarrow$ truecolor.
    6. Known 256-color terminals $\rightarrow$ 256 colors.
    7. Fallback: Unknown terminals $\rightarrow$ 16 colors.
  7. Robust input argument handling in Ansis

    master

    Unlike many other ANSI libraries, Ansis is designed to be resilient when passed non-string or empty arguments. It avoids producing strings like 'undefined' or 'null' and instead returns an empty string, which is the expected behavior for styling operations.

    InputAnsis Result
    undefined'' (empty string)
    null'' (empty string)
    '' (empty string)'' (empty string)
    ansis.reset()\e[0m (reset code)

    This makes Ansis safer for use in dynamic applications where data might be missing or malformed.

    ```js
    ansis.red()          // ''
    ansis.red(undefined) // ''
    ansis.red(null)      // ''
    ansis.red('')        // ''
    ansis.reset()        // \e[0m
    ```埋
  8. Handle edge cases: New lines and Nested template strings

    master

    Ansis provides robust handling for common ANSI styling edge cases that other libraries (like Picocolors or Chalk) may struggle with:

    Style breaks at New Lines

    Ansis automatically adds a style break at each new line. This ensures that multi-line text is styled correctly without leaking styles or breaking formatting.

    Nested Template Strings

    Ansis supports nested tagged template literals, allowing you to nest different styles within a single string expression.

    // Nested template strings work seamlessly in Ansis
    ansis.red`R ${ansis.green`G ${ansis.blue`B`} G`} R` 
    ```js
    ansis.bgRed('\n ERROR \n') + ansis.cyan('The file not found!') // ✅ Correctly handles new lines
    
    ansis.red`R ${ansis.green`G ${ansis.blue`B`} G`} R` // ✅ Supports nesting
    ```埋
  9. Migrate from Kleur to Ansis

    master

    Ansis is compatible with kleur styles and color names.

    Important Change for Kleur v3.0+ users: Kleur v3.0 uses chained method calls like green().bold(). Ansis uses a getter-based syntax. To migrate, replace the empty parentheses (). with a dot ..

    Example: Change green().bold() to green.bold().

    // From (Kleur v3):
    // green().bold().underline('message');
    // To (Ansis):
    green.bold.underline('message');
    
    // Optimized usage:
    yellow`foo ${red.bold`red`} bar ${cyan`cyan`} baz`;
  10. Test the default Ansis instance and imported app code

    master

    The default export and named styles in ansis are initialized upon import. Because they detect the color level only once, you cannot set process.env after importing ansis.

    To test the default instance or app code that uses ansis, you must use a setup file that defines the environment variables and import that setup file before importing ansis or your application code.

    // no-color.js
    process.env.NO_COLOR = '1';
    
    // app.js
    import color from 'ansis';
    export function formatMessage(message) {
      return color.red(message);
    }
    
    // test.js
    import { expect, test } from 'vitest';
    import './no-color.js'; // Must be first
    import { formatMessage } from './app.js';
    
    test('disables colors for imported app code', () => {
      expect(formatMessage('foo')).toBe('foo');
    });
  11. Run ansis benchmarks

    master

    To run the performance benchmarks locally, clone the repository, install dependencies, build the project, and execute the benchmark script.

    Note: Benchmarks are performed using benchmark.js. Avoid using vitest benchmark for performance comparisons as it produces incorrect/unreal results.

    git clone https://github.com/webdiscus/ansis.git
    cd ./ansis
    npm i
    npm run build
    npm run bench