Skip to content

Conversation

@serhalp
Copy link
Collaborator

@serhalp serhalp commented Jan 30, 2026

Compare 2-4 packages side-by-side at /compare with facets including:

  • Performance: package size, install size, dependencies (later: total deps)
  • Health: weekly downloads, last updated, deprecation status
  • Compatibility: TypeScript types, module format, (Node.js) engines
  • Security & Compliance: license, vulnerabilities

User can select which facets to display via checkboxes, with convenient groups and quick all/none buttons per group and globally.

URL is source of truth for selected packages and facets, allowing easy sharing.

The "total install size" metric is fetched lazily after initial load and rendered initially with a loading fallback, as it is quite slow to compute.

For numeric facets, a proportional bar is shown behind the value for easy visual comparison. The greatest value in the row is used as the 100% reference.

I tried to limit subjective/opinionated highlights and such, but I did add red for Deprecated, green for no vulns, green for included types and blue for external types (seems neutral enough...), and some basic yellow/red for egregious last updated time.

Screenshot 2026-01-29 at 22 53 31 Screenshot 2026-01-29 at 23 34 37 Screenshot 2026-01-29 at 22 47 26

Add a "Compare to..." entry point on package page (keyboard shortcut: c) and a "compare" top nav item.

Screenshot 2026-01-29 at 22 52 56 Screenshot 2026-01-29 at 23 38 16

Compare 2-4 packages side-by-side at `/compare` with facets including:
- Performance: package size, install size, dependencies (later: total deps)
- Health: weekly downloads, last updated, deprecation status
- Compatibility: TypeScript types, module format, (Node.js) engines
- Security & Compliance: license, vulnerabilities

User can select which facets to display via checkboxes, with convenient groups and quick all/none
buttons per group and globally.

URL is source of truth for selected packages and facets, allowing easy sharing.

The "total install size" metric is fetched lazily after initial load and rendered initially with a
loading fallback, as it is quite slow to compute.

For numeric facets, a proportional bar is shown behind the value for easy visual comparison. The
greatest value in the row is used as the 100% reference.

I tried to limit subjective/opinionated highlights and such, but I did add red for Deprecated, green
for no vulns, green for included types and blue for external types (seems neutral enough...), and
some basic yellow/red for egregious last updated time.

Add a "Compare to..." entry point on package page (keyboard shortcut: `c`) and a "compare" top nav
item.
@vercel
Copy link

vercel bot commented Jan 30, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
docs.npmx.dev Ready Ready Preview, Comment Jan 30, 2026 4:38am
npmx.dev Ready Ready Preview, Comment Jan 30, 2026 4:38am
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
npmx-lunaria Ignored Ignored Jan 30, 2026 4:38am

Request Review

@github-actions
Copy link

Lunaria Status Overview

🌕 This pull request will trigger status changes.

Learn more

By default, every PR changing files present in the Lunaria configuration's files property will be considered and trigger status changes accordingly.

You can change this by adding one of the keywords present in the ignoreKeywords property in your Lunaria configuration file in the PR's title (ignoring all files) or by including a tracker directive in the merged commit's description.

Tracked Files

File Note
lunaria/files/en-US.json Source changed, localizations will be marked as outdated.
lunaria/files/fr-FR.json Localization changed, will be marked as complete.
Warnings reference
Icon Description
🔄️ The source for this localization has been updated since the creation of this pull request, make sure all changes in the source have been applied.

<span
v-if="!info.comingSoon"
class="w-3 h-3"
:class="isFacetSelected(facet) ? 'i-carbon-checkmark' : 'i-carbon-add'"
Copy link
Contributor

Choose a reason for hiding this comment

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

can you use : as separator in the icons (small perf at UnoCSS) => i-carbon:add

<!-- Background bar for numeric values -->
<div
v-if="showBar && value && getBarWidth(value) > 0"
class="absolute inset-y-1 left-1 bg-fg/5 rounded-sm transition-all duration-300"
Copy link
Contributor

Choose a reason for hiding this comment

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

don't use left/right use inset-is and inset-ie respetivelly: check the contributing guide, RTL support => https://github.com/npmx-dev/npmx.dev/blob/main/CONTRIBUTING.md#rtl-support

<!-- Add package input -->
<div v-if="packages.length < maxPackages" class="relative">
<div class="relative">
<span class="absolute left-3 top-1/2 -translate-y-1/2 text-fg-subtle" aria-hidden="true">
Copy link
Contributor

Choose a reason for hiding this comment

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

same here for left

>
<div
v-if="isInputFocused && (filteredResults.length > 0 || isSearching)"
class="absolute top-full left-0 right-0 mt-1 bg-bg-elevated border border-border rounded-lg shadow-lg z-50 max-h-64 overflow-y-auto"
Copy link
Contributor

Choose a reason for hiding this comment

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

same here, left and right

v-for="result in filteredResults"
:key="result.name"
type="button"
class="w-full text-left px-4 py-2.5 hover:bg-bg-muted transition-colors focus-visible:outline-none focus-visible:bg-bg-muted"
Copy link
Contributor

Choose a reason for hiding this comment

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

use test-is instead text-left


<!-- Empty state -->
<section v-else class="text-center py-16 border border-dashed border-border rounded-lg">
<div class="i-carbon-compare w-12 h-12 text-fg-subtle mx-auto mb-4" aria-hidden="true" />
Copy link
Contributor

Choose a reason for hiding this comment

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

another icon

return 'i-carbon-arrow-down'
case 'changed':
return 'i-carbon-arrows-horizontal'
default:
Copy link
Contributor

Choose a reason for hiding this comment

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

3 icons here

<span class="text-xs text-fg-muted uppercase tracking-wider">{{ label }}</span>
<span
v-if="description"
class="i-carbon-information w-3 h-3 text-fg-subtle"
Copy link
Contributor

Choose a reason for hiding this comment

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

icon

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.

3 participants