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

@lxch/tan-dem

v0.2.0

Published

The easiest way to bring collaborative work to your application.

Readme

tan-dem

The easiest way to bring collaborative work to your application.

  • gif comes here
  • landing page comes here

Installation

  • npm i -S @lxch/tan-dem

  • const HOST = {PUBLIC_HOST}

  • <TandemProvider url={HOST} room={ROOM_NAME}>{...your app...}</TandemProvider>

  • need Vue, Svelte and Angular

Server

  • docker start @lxch/tan-dem-server
  • about rooms

Cursors

  • different types of cursors (pointer, caret, anything else?)
// connect
const { cursors, push } = useCursors<{ x: number, y: number }>();

// push current user info
React.useEffect(() => {
    const updateCursor = (e) => {
        push({ x: e.clientX, y: e.clientY });
    };

    window.addEventListener('mousemove', updateCursor);
    return () => window.removeEventListener('mousemove', updateCursor);
}, [push]);

// TODO color? name? push it all
return (
    <Relative>
        {cursors.map((cursor: { x: number, y: number, color: string }) => {
            return (
                <Absolute left={x} top={y}>
                    <CursorIcon color={color} />
                </Absolute>
            );
        })}
    </Relative>
);

Actions

  • when someone changes something of significance within your app
  • you push an action
  • more granular updates?
const App = () => {
    const [value, setValue] = React.useState('');

    const { push, on } = useAction<string>('update_value');

    // TODO can we merge it
    // can we leave both options? so no roundtrip
    React.useEffect(() => {
        return on((data) => {
            setValue(data);
        });
    }, [on]);

    const updateAndSetValue = React.useCallback((s: string) => {
        push(s);
        setValue(s);
    }, []);

    return (
        <Input value={value} onChange={updateAndSetValue} />
    );
};

Locks

  • sometimes you need to lock stuff just like in miro
const { locked, lock, unlock } = useLock('main_input');

return (
    {/* locked.cursor will contain user information that you have pushed before */}
    <Disabled disabled={locked}>
        <Input ref={useClickOutside(unlock)} onClick={lock} value={value} onChange={updateAndSetValue} />
    </Disabled>
);

Chat

  • simply separate component that
  • chat is pub sub (fan), so no storage

Calls

  • another components to just hop on a call

Comments

  • Comments need to be pricey? since it requires storage
  • need a "connector" docker env variable for storage (postgres/mongo?)
  • a bit of rabbit hole, need to simplify yet keep usable
  • Figma-like component

Other components

  • Timer (state on the server)
  • Voting

Custom Server Reducer

Timer and voting are built upon a Server Reducer module. This module gives you tooling to create your own state on server side and keep it in sync for all your clients. You can use it yourself and create custom state like:

  • Just like chat you can have custom components that will keep their state on the server
  • pretty much like dispatch
  • there things also require storage so need to be premium or something
const { state, dispatch } = useServerReducer('counter', (action, state) => {
    if (action.type === 'increment') {r
        return { counter: state.counter + 1 };
    }

    return state;
}, { counter: 0 });

return (
    <Counter count={state.counter} onClick={() => dispatch({ type: 'increment' })} />
);

Using with AI

  • need some kind of agents.md to make it easier for Cursor

Support

  • do not hesitate creating any issues
  • if you want premium go here (open collective link)

Other

  • library for server support?