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

tacl

v0.1.2

Published

Tools to help you make a tech-agnostic component library

Readme

Tech-Agnostic Component Library (TACL)

To create a component library using the basics (HTML, CSS, and JS), yet make them extendable into modern frontend libraries, like React, Angular, or VueJS. And because it's relying on the universal, basic web technology, it can also be used for other simpler web apps, like with a CMS.

Why

To share as much code between different frontend needs. Even if you have a static CMS site with limited JS, or a dynamic web app that's mostly JS code, you will still need UI components. Then your options are to do all the work twice or more, depending on your organization's needs, or you can consolidate the majority of your your code into one place.

Caveat: This is not for everyone, in fact, this is a niche problem. Most small companies will only have one tech stack, one component library, and so this would be an absolutely poor fit. However, with larger companies that have dozens of apps and teams and different tech stacks yet want to keep their UI more consistent and reduce maintenance, this might be of great value.

Architecture

A metaphor that can help think about this is instant ramen. The ramen noodles are the bulk of what's inside the packaging. It's universal and they sort of work alone but in actuality could use a flavor packet. The ramen noodles are your base library, while the specialized library would be the flavor packet. By making the noodles, you're 80% done with the work; now you only need to add some React, Angular, Vue or whatever flavor you get the remaining 20%.

Pros

  • Reduce duplicated work and maintenance for component libraries.
  • Work lasts longer. You can easily port your library to the new, trendy UI framework/library.

Cons

  • A bit more initial work than if you were to only create one component library, like an Angular-only component library.
  • Maintenance in Base Component Library needs a bit more thinking/caution to prevent issues downstream.

Base Library

./src
└───/components
    └───/MyCustomComponent
    │   └───/html
    │   │   └───structure.html
    │   │   └───example.html
    │   │
    │   └───/js
    │   │   └───index.js (AUTO-GENERATED)
    │   │   └───onClick.js
    │   │   └───someHelperFunction.js
    │   │
    │   └───/sass
    │   │   └───index.scss
    │   │
    │   └───/resources
    │       └───some-icon.svg
    │
    └───/MyOtherComponent

/html

The base library is where you create your HTML structure files. These describe what HTML elements and classes you want to use. You can also comment the optional and conditional classes above the target element.

/sass

The only requirement with your CSS is to use an index.scss file in the /sass folder. You can from there @include any additional SCSS files you want; if you're looking to organize with smaller files. The SCSS will autocompile to CSS for you.

/js

If the component has any functionality, like having state and updating it on a click, you can create functions to standardize how it handles those events. Please break them up by individual files for each function, using the same name. For example, if your exported function is called onClick, then call your file onClick.js.

Note: Please do not use export default; it does not support this feature.

Here's an example:

// helloFoobar.js
import { sayHello } from './utils';

export function helloFoobar(foobar) {
  return sayHello(foobar);
}

/*
  Key Notes:
  + The exported variable is the same name as the file.
  + You can reference other non-exported functions/variables/classes from other files without issues.
  - Not using "export default".
*/

Specialized Library

This is the tech-flavor packet to evolve the base library into a React component library (for example). It should mirror the Base Component Library but have all the importable code within src/components/<YOUR-COMPONENT>/tacl folder.

Setup

Config Files

In each of your component libraries' repo, add a .taclrc file.

In your Base Component Library repo:

{
  "role": "base"
}

In your Specialized Component Library repo:

{
  "role": "specialized",
  "baseRepo": "https://github.com/your-username/your-base-repo.git"
}

Writing Base Component

  1. Create a new component under this structure: base-repo/src/components/<YOUR-COMPONENT-NAME>.
  2. Add base-repo/src/components/<YOUR-COMPONENT-NAME>/html/structure.html file.
  3. Write your semantic HTML.
  4. Add base-repo/src/components/<YOUR-COMPONENT-NAME>/sass/index.scss file.
  5. Write your CSS using Sass.
  6. For each function you need, create a separate JS file under: base-repo/src/components/<YOUR-COMPONENT-NAME>/js/<YOUR-FUNCTION-NAME>.js.
  7. Add JS code.
  8. Run the command tacl compile to ensure there's no errors.
  9. Save files, commit, and push to origin/master.

Your base component code is now available to port into your Specialized Component Library.

Specializing a Component

From your Specialized Component Library, after it has been configured properly, you can run the command: tacl sync.

This should scaffold your component library for you. It should essentially mirror your base component library but it places the code under a /tacl folder instead, like: specialized-repo/src/components/<YOUR-COMPONENT-NAME>/tacl.

For example, for React, you can create an index.js file under specialized-repo/src/components/<YOUR-COMPONENT-NAME>/index.js.

import React, { Component } from 'react';

// import styles and  scripts for this component from the Base Component Library
import { onClick } from './tacl/scripts';
import './tacl/styles.css';

class MyCustomComponent extends Component {
  state = {
    count: 0,
  };

  onClick = () => {
    const { state } = this;
    const newState = onClick({ state }); // Using the 'onClick' imported from './tacl/scripts'...
    this.setState(newState);
  };

  render () {
    return (
      <button
        className="my-custom-component"
        onClick={this.onClick}
      >
        {this.state.count}
      </button>
    );
  }
}

export default MyCustomComponent;

This example shows that there's minimal work being done in the Specialized Component Library. The function, state management, styles, and elements rendered should all come from the Base Component Library. Essentially, we're only making the component usable within a React project.

This also means that there's little maintenance required within the Specialized Component Library. If there's an issue it most likely will be addressed within the Base Component Library.