Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor!: replace ansi-colors with smaller and faster ansis #5274

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

webdiscus
Copy link

@webdiscus webdiscus commented Dec 17, 2024

PR Checklist

Overview

This PR replaces the outdated ansi-colors (last update 3 years ago) package with smaller and faster ansis.

Benefits of ansis

  • Supports both ESM and CommonJS
  • Supports Bun and Deno runtimes
  • Supports TypeScript
  • Ansis is compatible with ansi-colors API, plus supports named import: import { red, yellow } from 'ansis'
  • Installed package size only 10 kB (ansi-colors 26 kB), see Compare the size of most popular packages
  • 7-10x faster than ansi-colors, see Benchmarks
  • Using named import your code will be clean and more readable:
    - console.error(ansi.red(`Error: ${result.error.message}`));
    + console.error(red`Error: ${result.error.message}`); // <= shorter and more readable
  • Supports ANSI 256 colors and TrueColor with Fallback: TrueColor → 256 colors → 16 colors → no colors
  • Supports environment variables NO_COLOR FORCE_COLOR and flags --no-color --color
  • Both Ansis and Picocolors (does't support named import) are recommended by the ES Tooling community as smallest and fastest packages.

Packages that already use ansis

Test

This PR does not require unit/integration tests.

But you can do the manual test.

Install the fork

git clone https://github.com/webdiscus/mocha.git
cd mocha
git checkout switch-to-ansis
npm i
npm run build

Test changed files

Cmd:

node ./bin/mocha.js -h

In console output will be displayed color text:
Other Options

Cmd:

node ./bin/mocha.js -h --no-color

In console output will be displayed b&w text:
Other Options

Cmd:

node ./bin/mocha.js -R

In console output will be displayed red text:
Error Not enough arguments following R

Copy link
Member

@JoshuaKGoldberg JoshuaKGoldberg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey thanks for sending this in @webdiscus!

In the future, could you please file issues before sending nontrivial PRs? Per our contributing guidelines we prefer discussing changes before implementing. It can be hard to know whether an approach is the right one to spend development time on, and it's awkward telling someone to redo lots of work.

This PR is a good example of that: it's not clear to me why you'd want ansis (300k weekly downloads) over picocolors (31m weekly downloads).

I'll note that per https://github.com/webdiscus/ansis?tab=readme-ov-file#-unpacked-size, picocolors is both a smaller size and faster when applying single styles. But both of those are such negligibly small differences that I doubt they matter for Mocha's usage.

@JoshuaKGoldberg JoshuaKGoldberg marked this pull request as draft January 2, 2025 05:15
@JoshuaKGoldberg
Copy link
Member

👋 Ping @webdiscus - do you have thoughts on ansis vs. picocolors? I'm generally in favor of e18e-style changes like this, but want to be thorough in applying the right ones.

@JoshuaKGoldberg JoshuaKGoldberg added the status: waiting for author waiting on response from OP - more information needed label Feb 4, 2025
@webdiscus
Copy link
Author

webdiscus commented Feb 4, 2025

👋 Ping @webdiscus - do you have thoughts on ansis vs. picocolors? I'm generally in favor of e18e-style changes like this, but want to be thorough in applying the right ones.

Hello @JoshuaKGoldberg,

I'm sorry, I thought you had already decided to close this PR.

I'm the author of the ansis.
Today these are the two smallest and fastest libraries: picocolors and ansis, both are recommended by the e18e community.

My goal is to help in choice the most suitable replacement for older, larger libraries.
I want to open eyes and show an honest comparison of different libraries with their "pros" and "cons". So that developers can see the whole list of good libraries, and not blindly trust only Picocolors.

Size

Ansis is almost as small as Picocolors:

The difference is 0.4 kB, but Ansis has the functionality of Chalk.

Performance

Caution

All libraries are more than fast enough. The benchmark results only to show the effectiveness of micro-optimizations in the code, which does not impact on real-world usage.

Picocolors doesn't handle important edge cases, so it is the fastest and smallest.

  • picocolors is fastest when applying a single style (e.g., red) only.
  • ansis is fastest when applying two or more styles (e.g., red + bgWhite).

Which One Should You Use?

Here is the checklist:

  • Does it matter if a library performs ~60 million or ~100 million ops/sec when outputting to the terminal?
    Spoiler: Both Ansis and Picocolors are more than fast enough.
    • ✅ Picocolors
    • ❌ Ansis
  • Does it matter if the unpacked size is 6.4 kB or 6.8 kB, a difference of 0.4 kB?
    • ✅ Picocolors
    • ❌ Ansis
  • Does support for ANSI 256 colors or Truecolor with fallback matter?
    • ✅ Ansis
    • ❌ Picocolors
  • Does handling edge cases matter?
    • ✅ Ansis
    • ❌ Picocolors
  • Does supporting a wide range of environments matter?
    • ✅ Ansis
    • ❌ Picocolors
  • Does keeping your code clean and readable matter?
    (e.g., using named import, chained syntax, nested template strings)
    • Ansis:
    // using named import:
    green`Create ${blue.bold`React`} app.`
    // or using default import:
    ansis.green`Create ${ansis.blue.bold`React`} app.`
    • Picocolors:
    pico.green(`Create ${pico.blue(pico.bold('React'))} app.`)

Yes, you are right, in these concrete use cases, in Mocha, Picocolors is enough.
But if you wish a stable powerful library with the same small size for perspective in future, then Ansis may be good choice.

ansis ~300k weekly downloads

During the New Year period, NPM had a drop in statistics, as it does now :-/
But Ansis has over 1 million weekly downloads, which is enough to be considered popular, although not as popular as Picocolors.

What is your final decision?

If you choose Picocolor, I respect it. 👍🏻
No problem, I make new PR with Picocolors.

@JoshuaKGoldberg
Copy link
Member

JoshuaKGoldberg commented Feb 5, 2025

Performance

Agreed, they're all fast enough that it doesn't matter for Mocha's use case.

Does keeping your code clean and readable matter?
(e.g., using named import, chained syntax, nested template strings)

😁 I appreciate and respect that you're paying attention to this, but personally disagree with the ✅ / ❌ framing of the opinion. That's a stylistic preference I don't share. I actually prefer a single named export like ansi, chalk, etc.


Anyway, this is getting to be a longer discussion and we generally use issues for that. I'm going to go ahead and file a new issue. Thanks for starting the discussion!

Steps in CONTRIBUTING.md were taken

In the future I'd recommend going through the contributing guidelines and filing an issue first. As a fellow open source maintainer I feel bad drafting or closing a PR that had good + earnest work put into it like this one.

@JoshuaKGoldberg JoshuaKGoldberg removed the status: waiting for author waiting on response from OP - more information needed label Feb 5, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants