npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@hdnax/genuix

v0.15.0

Published

A personal design system - Gene + UI/UX = Genuix.

Readme

Genuix

Status Version License

A personal design system with DNA in its name - Gene + UI/UX = Genuix (sounds like "genuine-x").

Also a place to document my findings of building a design system.

Progress tracker: Design System Home

Motivation

  • Sharpen frontend skills - both logic and visual design.
  • Learn how design systems are built and maintained.
  • Explore UI/UX best practices hands-on.
  • Build personal libraries to use across my projects.

Component Design

API Design

Some types of APIs to consider for a modular piece of UI + logic:

  • Simple reusable components.
  • Simple composables.
  • Compound components with provide/inject.
  • Vue directives.
  • Scoped slots.
  • data-* attributes.

Some may be more suitable than others depending on the scenarios.

Token Inversion Problem

When a non-primary child component sits on a solid surface, it needs inverted colors to stay readable.

One way is to have the child components aware of their rendering contexts & change their styles based on that. But it's adhoc and we can't possibly account for the possible types of surfaces they are rendered on.

Another way is to have the consumer (parent components) remap the design tokens, so the child components stay agnostic of the context.

Example: invertTokens(semantic) remaps --gui-{semantic}-* CSS custom properties on a container element:

fg       -> bg        (dark text becomes light)
fg-muted -> bg-subtle (muted text becomes subtle light)
border   -> bg-active (border visible on solid surface)
bg-hover -> solid-hover (hover state works on solid surface)

Usage: apply the returned style object on the container, and any child component reading --gui-{semantic}-* automatically gets contrast-correct values with zero overrides.

I believe Radix Themes handles it like this.

The general rule: parent owns the context, children stay generic.

This is another reason why we should use semantic design tokens.

Overridable Default Styling for Components

One problem that I faced was that:

  • I wanted to have intricate stylings for my components.
  • But, I wanted my components' stylings to be overridable.

Previously, I was styling the components like this:

<template>
  <div id="div-1" class="gui-neutral-bg-subtle" />
  <!-- Or -->
  <div id="div-2" class="my-div" />
</template>

<style scoped>
.my-div {
  ...
}
</style>

I wondered, can the consumer override these styles? If the root child component receive the fall through styles/classes they shall conflict, understandably.

So, I decided to use @layer: Component styles are placed inside @layer components. CSS layer precedence means unlayered styles always win over layered ones, regardless of specificity. This lets consumers override any component style via the class prop without !important.

This keeps the override hierarchy clean: component defaults (layered) < consumer classes (unlayered).

Semantic Styling

A problem when design GTextInput: I want to allow the text input to have multiple states (success, warning, error, default). Therefore, the consumer should be allowed to pass the current input state to the component.

In other components that I implemented, I sometimes used this pattern:

<!-- Component internals -->
<template>
  <input
    :class="{
      'text-input--error': state === 'error',
      'text-input--warning': state === 'warning',
      'text-input--success': state === 'success',
    }"
  />
</template>

<style scoped>
.text-input--error {
  @apply gui-danger-border;
}

.text-input--warning {
  @apply gui-warning-border;
}

.text-input--success {
  @apply gui-success-border;
}
</style>

However, the problem is that, what if I want the consumer to style the exact state of a component?

  1. A possible solution is to make the .text-input--error classes part of the public API, but I think this is somewhat leaky & adhoc as I have always added classes in a somewhat free-styling manner & text-input is an implementation detail.
  2. Another solution is to add props such as error-class, warning-class. However, it seems verbose and doesn't scale.
  3. Exposing via class prop leaks implementation. If an error state later adds a background change, every consumer override breaks.

So I ended up with data-* attributes, denoting the current state of the component:

<!-- Component internals -->
<template>
  <input :data-state="state" />
</template>

<style scoped>
@layer components {
  .text-input[data-state="error"] {
    @apply gui-danger-border;
  }

  .text-input[data-state="warning"] {
    @apply gui-warning-border;
  }
}
</style>
<!-- Consumer: style based on state without knowing implementation -->
<GTextInput state="error" />

The data-* attribute is also queryable by parent CSS selectors (e.g. via :has([data-state="error"])), which none of the other approaches support.

@import CSS Inside a Selector

When adding highlighting themes to GCodeBlock, I tried this approach by importing the highlight.js provided themes in the CSS selector:

<template>
  <!-- highlightTheme can be github, github-dark, etc. -->
  <div
    id="code-block"
    :theme="highlightTheme"
  >
  </div>
</template>

<style scoped>
#code-block {
  &.github {
    @import 'highlight.js/styles/github.css';
  }

  &.github-dark {
    @import 'highlight.js/styles/github-dark.css';
  }
}
</style>

This built without errors, but styles failed to be applied. I checked the browser's CSS and it yielded some malformed CSS.

I finally learnt that this was not supported, even with or without build tools.

The solution I found is using sass:

@use "sass:module";

#code-block {
  &.github {
    @include meta.load-css('highlight.js/styles/github.css');
  }
}

Should Set Explicit Button Type

By default, buttons default to the submit type, which is almost always undesriable for SPA apps.

Transitive Cascading of CSS Variables

When defining inverted color tokens, I encountered this:

:root {
  --color-a: var(--color-b);
}

.child {
  --color-b: #123456;
  color: var(--color-a);
}

I thought color would be #123456, as color is set to var(--color-a), which is originally set to var(--color-b). Therefore, I thought var(--color-a) would inherit that.

However, that wasn't the case. Maybe variables in CSS are not simply aliases...

Tailwind v4 Deprecation of Preprocessors

scss no longer works with tailwindcss v4.