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

@ricsam/react-tunnel

v0.0.5

Published

This package allows you to define where you want components to end up in the react component hierarchy. It is like a managed react portal. This is useful if you are dealing with contexts or different React renderers like react-three-fiber or react-art. Th

Readme

@ricsam/react-tunnel

This package allows you to define where you want components to end up in the react component hierarchy. It is like a managed react portal. This is useful if you are dealing with contexts or different React renderers like react-three-fiber or react-art. The code is quite simple, so instead of installing this package from npm you can just copy the code from index.tsx and use it in your project.

npm i @ricsam/react-tunnel

Usage

import { createTunnel, InTunnel, OutTunnel } from "@ricsam/react-tunnel";

// Create a tunnel instance
const tunnel = createTunnel();

// In your layout component
function Layout() {
  return (
    <div>
      <h1>Header</h1>
      <OutTunnel tunnel={tunnel} /> {/* Content will appear here */}
      <div>Other content</div>
    </div>
  );
}

// Deep in your component tree
function DeepComponent() {
  return (
    <div>
      <h2>Deep component</h2>
      <InTunnel tunnel={tunnel}>
        <div>This content will appear after Header</div>
      </InTunnel>
    </div>
  );
}

Examples

Modal Portal

const modalTunnel = createTunnel();

function App() {
  return (
    <div>
      <OutTunnel tunnel={modalTunnel} />
      <PageContent />
    </div>
  );
}

function Modal({ children, isOpen }) {
  if (!isOpen) return null;
  return (
    <InTunnel tunnel={modalTunnel}>
      <div className="modal">{children}</div>
    </InTunnel>
  );
}

Multiple Targets

const primaryTunnel = createTunnel();
const secondaryTunnel = createTunnel();

function Layout() {
  return (
    <div>
      <nav>
        <OutTunnel tunnel={primaryTunnel} />
      </nav>
      <aside>
        <OutTunnel tunnel={secondaryTunnel} />
      </aside>
    </div>
  );
}

function Feature() {
  return (
    <>
      <InTunnel tunnel={primaryTunnel}>
        <PrimaryNavContent />
      </InTunnel>
      <InTunnel tunnel={secondaryTunnel}>
        <SidebarContent />
      </InTunnel>
    </>
  );
}

Dynamic Tunnels

const TunnelContext = createContext<Tunnel>(createTunnel());
function useTunnel() {
  return useContext(TunnelContext);
}

// Use tunnels in your app
function App() {
  const tunnel = useMemo(createTunnel, []);
  return (
    <TunnelContext.Provider value={tunnel}>
      <OutTunnel tunnel={useTunnel().modal} />
      <Content />
    </TunnelContext.Provider>
  );
}

// Consume tunnel anywhere
function Content() {
  const tunnel = useTunnel();
  return (
    <InTunnel tunnel={tunnel}>
      <div>This appears at OutTunnel</div>
    </InTunnel>
  );
}

Extra utils

useTunnelIsOpen

Hook to detect if any InTunnel is currently rendering content. Useful for conditionally rendering OutTunnel wrappers:

function App() {
  const open = useTunnelIsOpen(tunnel);
  return (
    <>
      {open && (
        <SidebarWrapper>
          <OutTunnel tunnel={tunnel} />
        </SidebarWrapper>
      )}
      <MySidebar />
    </>
  );
}
function MySidebar({ children }) {
  return <InTunnel tunnel={tunnel}>{children}</InTunnel>;
}

API

createTunnel()

Creates a new tunnel instance.

<InTunnel tunnel={tunnel}>

Sends children to the corresponding OutTunnel. Only one InTunnel is allowed per tunnel.

<OutTunnel tunnel={tunnel}>

Renders content from the corresponding InTunnel. Multiple OutTunnels can share the same tunnel.

Restrictions

  • Only one InTunnel is allowed per tunnel instance
  • Content is cleared when InTunnel unmounts
  • OutTunnel must be mounted before InTunnel for content to appear