Building class-glue: A Journey into Modern Package Development

shettayyy

Rahul Shetty

Posted on October 27, 2024

Building class-glue: A Journey into Modern Package Development

The Journey Begins 🚀

I recently decided to dive into open-source contribution by building something I needed in my day-to-day development: a utility for handling CSS class names that works seamlessly with CSS Modules and React Native styles.

The Problem 🤔

If you've worked with CSS Modules or React Native, you've probably written code like this:

// CSS Modules
className={`${styles.container} ${isActive ? styles.active : ''}`}

// React Native
style={[styles.container, isActive && styles.active]}
Enter fullscreen mode Exit fullscreen mode

While libraries like clsx help with class name construction, they don't directly support style objects. This is where class-glue comes in.

The Solution 💡

class-glue provides a unified API for handling both class names and style objects:

// CSS Modules
import createModuleGlue from 'class-glue/merge-module-strings';
import styles from './Card.module.css';

const clgl = createModuleGlue(styles);

function Card({ isHighlighted }) {
  return (
    <div className={clgl('card', { cardHighlighted: isHighlighted })}>
      {/* Resolves to actual CSS Module classes */}
    </div>
  );
}

// React Native
import createStyleGlue from 'class-glue/merge-styles';

const styles = {
  container: { padding: 16, borderRadius: 8 },
  active: { backgroundColor: 'blue' }
};

const clgl = createStyleGlue(styles);

function Card({ isActive }) {
  return (
    <View style={clgl('container', { active: isActive })}>
      {/* Merges styles based on conditions */}
    </View>
  );
}
Enter fullscreen mode Exit fullscreen mode

Technical Deep Dive 🔍

Installation

You can install using your favourite javascript package manager but for the sake of this post -

npm add class-glue
Enter fullscreen mode Exit fullscreen mode

NPM Link: https://www.npmjs.com/package/class-glue
GitHub Link: https://github.com/shettayyy/class-glue

Modular Architecture

The library is split into focused utilities:

  • class-glue: Core functionality
  • join-strings: String-only operations
  • keys-to-strings: Object-based class generation
  • merge-module-strings: CSS Modules support
  • merge-styles: Style object handling

Each utility is independent and tree-shakeable, ensuring you only bundle what you use.

Bundle Size Optimization

One interesting learning was that for such a small utility, a bundler wasn't necessary. The raw, minified code was already optimal. The entire package is just 425B gzipped!

Type Safety

TypeScript support was a priority. Here's how we handle type inference:

import type { ClassValue } from 'class-glue';

function Button<T extends string>({ className, variant }: {
  className?: ClassValue;
  variant?: T;
}) {
  // Full type safety and inference
}
Enter fullscreen mode Exit fullscreen mode

Learnings & Insights 📚

Building this package taught me several valuable lessons:

  1. Less is More: For small utilities, avoiding bundlers can actually lead to smaller package size
  2. Module Systems: Supporting both CommonJS and ESM requires careful consideration
  3. NPM Workflow: Understanding pre/post scripts and entry points
  4. GitHub Features: Branch rulesets, discussions, sponsorship setup
  5. Documentation: The importance of clear, example-driven docs

Get Involved 🤝

The project is open source and welcomes contributions! You can:

  • Star the repository
  • Try it out: npm install class-glue
  • Provide feedback
  • Contribute code or documentation

GitHub Link: https://github.com/shettayyy/class-glue

Conclusion

What started as a simple utility grew into a learning journey about modern package development. The biggest takeaway? No contribution to open source is too small - you often gain more knowledge than you give.

💖 💪 🙅 🚩
shettayyy
Rahul Shetty

Posted on October 27, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related