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

@vanilla-wave/ez-di

v0.0.3

Published

Tiny dependency injection React library

Downloads

4

Readme

EZ-DI

ALPHA VERSION. NOT FOR PRODUCTION USAGE

Proof of concept tiny dependency injection React library.

  • Small (< 0.5 Kb)
  • Easy to use
// some components in project
const ButtonBase = () => <button className="base"></button>
const RedButton = () => <button className="red"></button>

// import diBlock and DiProvider
import { DiProvider, diBlock } from '@vanilla-wave/ez-di';

// 1. in target component. Make component swapable
const Button = diBlock('Button')(ButtonBase)

// 2. Wrap in provider and set desired component in registry
const  App = () => (
  <DiProvider registry={{ Button: RedButton }}>
    <Button />
  </DiProvider>
)

// result
// <button class="red"></button>

Install

npm i @vanilla-wave/ez-di

How it works

Main idea - give opportunity to swap components in app tree without writting code.

Wrapping component into diBlock('ComponentName', Component) creates slot. In place of component <Button /> appears slot with name SubmitButton. There are no changes in render, because default slot value - component itself.

const ButtonComponent = (...) => (...)
const Button = diBlock('SubmitButton', ButtonComponent)

const App = () =>  (
  <form className="some-form">
    {'...'}
    {/* inside Button there are slot with name 'SubmitButton' */}
    <Button />
  </form>
)

You can set component for slot in registry <DiProvider registry={...}>

When you set in registry component with name SubmitButton, it will be render in place of <Button />.

const ButtonComponent = (...) => (...)
const Button = diBlock('SubmitButton', ButtonComponent)

const RedButton = () => (/* Another Button */)

const App = () =>  (
  <DiProvider registry={{ SubmitButton: RedButton }}>
    <form className="some-form">
      {'...'}
      {/* here RedButton will be rendered */}
      <Button />
    </form>
  </DiProvider>
)

You can nest DiProvider. Registry value will be merged. It useful, when you need another override for part of application.

How to start

  1. Find replacable part in your app. Wrap them in diBlock and specify name. You will use it later to swap component. Also you can use explicit typing diBlock<RegistryType> to prevent type errors.
interface RegistryType {
  Button: React.ComponentType<ButtonPropsType>;
}

const ButtonBase: FC<ButtonPropsType> = ({ label }) => (
  <button className="base">{label}</button>
);
const Button = diBlock<RegistryType>('Button')(ButtonBase);
  1. Wrap your app in DiRegistry. Optional – you can use registry typpe here <DiProvider<RegistryType> ... >
interface RegistryType {
  Button: React.ComponentType<ButtonPropsType>;
}

const OverrideButton: FC<{ label: number }> = ({ label }) => (
  <button className="override">{label}</button>
);

const App = () => (
  <div>
    {/* @ts-expect-error */}
    <DiProvider<RegistryType> registry={{ Button: OverrideButton }}>
      <Button label="123" />
    </DiProvider>
  </div>
);
  1. Create components for slots. When you set component in registry it will render instead of default component(wrapped in diBlock)

Important – override component should have same props as base components.

const RedButton: FC<ButtonPropsType> = ({ label }) => (
  <button className="override">{label}</button>
);
  1. Now you can manage slots content with registry value. For example:
  • set another components for mobile device
  • set another component if user in experiment
  • etc

Falsy value will be ignored, and default component will be rendered.

const registry = {
  Button: isUserInExperiment ? RedButton :  undefined,
}

const App = () => (
  <DiProvider registry={{ Button: OverrideButton }}>
    <Button label="123" />
  </DiProvider>
);

PROJECT TODO

  • Registry control. Dynamicly add/remove/swap components.
  • library parts description in README

Created using TSDX