Skip to content

Conversation

delucis
Copy link
Member

@delucis delucis commented Oct 21, 2025

Changes

  • Uses picocolors instead of kleur for terminal text styling
  • Why? picocolors is slightly smaller and faster, but more importantly, after perf: switch to clack for CLI prompts #14589 none of our other dependencies will be using kleur, so switching like this would mean we align with what the rest of our dependencies use for colours, allowing us to drop a package from our dependency tree
kleur vs picocolors benchmarks
kleur picocolors diff
Install size 20.3 kB 6.37 kB -68%
Library loading time 0.773 ms 0.466 ms -40%
Simple usage 35,415,770 ops/sec 33,271,645 ops/sec +6%
Complex usage 1,129,526 ops/sec 2,024,086 ops/sec -44%

Source: https://github.com/alexeyraspopov/picocolors#benchmarks

Testing

Did some quick local CLI commands to test it out. Existing CI should pass.

Docs

n/a implementation detail

Copy link

changeset-bot bot commented Oct 21, 2025

🦋 Changeset detected

Latest commit: 0f938c1

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions github-actions bot added pkg: integration Related to any renderer integration (scope) pkg: astro Related to the core `astro` package (scope) labels Oct 21, 2025
Copy link

codspeed-hq bot commented Oct 21, 2025

CodSpeed Performance Report

Merging #14598 will not alter performance

Comparing chris/picocolors (0f938c1) with main (63b2568)1

Summary

✅ 6 untouched

Footnotes

  1. No successful run was found on main (99f4ebc) during the generation of this report, so 63b2568 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

import { exec } from './exec.js';

const require = createRequire(import.meta.url);
const { bold, cyan, dim, magenta } = colors;
Copy link
Member Author

Choose a reason for hiding this comment

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

In most modules, I refactored to use colors.method() directly, but in a couple like this one where there’s heavy use of the APIs, I kept the destructured approach to minimize code changes and keep usage a bit cleaner.

Comment on lines +330 to +332
return mv.annotation
? `${style(String(mv.value))} ${dim(mv.annotation)}`
: style(String(mv.value));
Copy link
Member Author

@delucis delucis Oct 21, 2025

Choose a reason for hiding this comment

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

I suspect this isn’t technically required, but picocolors types don’t allow boolean arguments like kleur did, and the usage here sometimes includes them. Coercing with String() every time should be fine in this case given the astro preferences CLI is rarely run and not performance sensitive.

Comment on lines -21 to -22
// Disable colors when running tests
kleur.$.enabled = false;
Copy link
Member Author

Choose a reason for hiding this comment

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

I wasn’t 100% sure of the intention here, but tests pass without this and picocolors does not have an equivalent API, so I removed it.

@delucis delucis marked this pull request as ready for review October 21, 2025 19:37
import colors from 'picocolors';
import type { TextStyler } from '../definitions.js';

export function createTextStyler(): TextStyler {
Copy link
Member

Choose a reason for hiding this comment

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

Can you rename it to createPicolorsTextStyler() (and the filename)? Like here it's useful to have it in the name, it's not an implementation detail

Copy link
Member Author

Choose a reason for hiding this comment

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

Oh, interesting!

Why do we have a generic TextStyler type then? Feels like if it’s not an implementation detail, wouldn’t it use a type of its own? And does that mean we’d have multiple stylers?

It just felt weird that to switch out a package, I also had to rename this, but maybe that’s intentional.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pkg: astro Related to the core `astro` package (scope) pkg: integration Related to any renderer integration (scope)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants