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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@merkl/conduit

v0.0.4

Published

An opiniated light-weight TypeScript code-splitting and dependency injection library for organizing your code.

Downloads

4,727

Readme

conduit

An opiniated light-weight TypeScript code-splitting and dependency injection library for organizing your code.

Why ?

Conduit was built to handle code-splitting and dependency issues that arises when your codebase gets bigger. It provides a minimal set of functions to handle create modules, services, and dependencies fully typed and declarative. It allows for a cleaner import tree since all the dependencies are evaluated at runtime, your service only imports the types of other services. This approach is efficient for the frontend as speeds up hot module reloading, and for the backend as it unlocks all the feature that dependency injection provides when using database or cache clients, development setups etc...

How do I use it

Conduit is pretty flexible, you could just use it to declare dependency-inject bits of code that is modular:

//user.service.ts

export const UserService = createConduit<{ api: ApiClient; config: any, repository: }>((inject) => {

    const getUser = inject(["api"], ({api}, query: {id: string}) => {
        return api.users.find({where: {id}})
    })

    const count = inject("api").pipe(({api}, query: {id: string}) => {
        return api.users.count({})
    })

    return {
        getUser,
        count
    };
}

You can then use anywhere like this:

//anywhere.ts

import {UserService} from "<path>";
import {apiClient: prod} from "./api.prod"
import {apiClient: staging} from "./api.staging"

const myUserFromProd = UserService({api: prod});
const myUserFromStaging = UserService({api: staging});

Go deeper and split your services and repositories and abstractions:

//user.repository.prisma.ts
type UserRepository = {count: () => number};

export const UserRepositoryWithPrisma: AUserRepository = createConduit<{ prisma: PrismaClient; }>((inject) => {

    const count = inject(["prisma"]).in(({prisma}) => {
        return prisma.users.find({where: {id}})
    })

    return {
        count
    } satisfies AbstractUserRepository;
})

//user.repository.drizzle.ts

export const UserRepositoryWithDrizzle: AUserRepository = createConduit<{ drizzle: DrizzleClient; }>((inject) => {

    const count = inject(["drizzle"]).in(({drizzle}) => {
        return drizzle.users.length()
    })

    return {
        count
    } satisfies AbstractUserRepository;
})
//user.service.ts
import type {UserRepository} from "<path>"

export const UserService = createConduit<{ repository: UserRepository; config: any, repository: }>((inject) => {

    //Define related utils functions and export them
    const hashId = (username: string, joinTime: string) => hash([username, joinTime]);

    //Access data via repository
    const count = inject("repository").in(({repository}) => {
        return repository.count()
    })

    return {
        hashId,
        count
    };
}

And the cherry on top, You can use partial conduits ! Making it easy to group related code without having to provide more dependencies that your usecase needs and this provides amazing DX with Typescript.

const userServiceWithDrizzle = UserService({ repository: UserRepositorWithDrizzle({drizzle}) })

userServiceWithDrizzle.hashId("flip", "102938"); //✅
await userServiceWithDrizzle.count(); //✅

const minimalUserService = UserService({});

minimalUserService.hashId("flip", "102938"); //✅
await userServiceWithDrizzle.count(); //❌