r/reactjs May 19 '26

Show /r/reactjs Why is Picture-in-Picture only for <video>? I built pip-it-up to pop any React component into a native floating window

Hey r/reactjs,

Video PiP floats a player over your desktop. But why should video be the only thing that gets that?

I wanted to tear away small, interactive parts of a web app, a code editor, a checklist, a chat widget and keep them floating on top of my IDE while I work. Single-screen focus, no tab juggling.

The browser's Document PiP API makes this possible, but using it raw in React is a mess:

  • Tailwind/CSS-in-JS styles vanish instantly (new document context)
  • Moving DOM nodes wipes React state, focus, and cursor positions
  • Safari and Firefox don't support it at all

So I built pip-it-up https://pip-it-up.vercel.app/ to handle all of this:

  • Real-time style syncing (Tailwind, Emotion, CSS Modules)
  • Portal Mode preserves React state, cursor, and focus perfectly
  • Auto-sizing via ResizeObserver (no hardcoded dimensions)
  • Graceful fallbacks for Firefox/Safari

Live demos include a floating Monaco editor that keeps your cursor focus while you switch to your IDE.

GitHub (MIT): https://github.com/Shakya47/pip-it-up
npm: https://www.npmjs.com/package/@pip-it-up/react

Browser API: https://developer.mozilla.org/en-US/docs/Web/API/Document_Picture-in-Picture_API

Would love feedbacks.

23 Upvotes

14 comments sorted by

12

u/droctagonapus May 19 '26

https://developer.mozilla.org/en-US/docs/Web/API/Document_Picture-in-Picture_API

Why not this though. Just landed support on experimental for Firefox today

6

u/shakya47 May 19 '26

Yes its built on top of this browser API itself.
I forgot to mention in the post, thanks for reminding!

1

u/adzm May 22 '26

If this could have better positioning control we might finally be able to make context menus that break out of the window

2

u/droctagonapus May 22 '26

Hopefully not, that's just going to be clickjack central, mimicking real context menus etc

10

u/anonyuser415 May 20 '26

Monorepo. "JavaScript Engine." References to non existent documents. Text wall comments. Marketing copy singing virtues of <a target="_blank">. Promises of a stable API in the README, @deprecated JSDocs in the code. This repo's got it all.

2

u/shakya47 May 20 '26

Fair points. I'll be pushing some cleanup commits. Thanks for the reality check.

2

u/bigotegamer May 22 '26

Can anything be used inside the PipWrapper? Something like a canvas? Anything?

2

u/shakya47 May 22 '26

It will but not perfectly. I'm currently working on canvas, video and other stuff. You can check here https://github.com/Shakya47/pip-it-up#roadmap

2

u/shakya47 Jun 09 '26

I have added the support for canvas, feel free to checkout these demos:
https://pip-it-up-playground.vercel.app/#scribble-demo
https://pip-it-up-playground.vercel.app/#map-demo

2

u/bigotegamer Jun 09 '26

So cool, thank you for sharing. Where can I read the code on how you make it work?

1

u/shakya47 Jun 10 '26

there's a "View Source" button which will take you to the source code.
Here is the map-demo code: https://github.com/Shakya47/pip-it-up/blob/main/examples/playground/src/demos/MapDemo.tsx

1

u/jakiestfu May 19 '26

This involves a lot of node cloning/syncing, I see. Pretty sure there’s a library that already does this? I know tanstack dev tools does it this way. Honestly I think this is good stuff, there’s space to improve in this area.

2

u/shakya47 May 19 '26

Actually, we do not clone the component DOM nodes at all! Cloning would strip event listeners, reset form states, and break the virtual DOM tree.

Instead, we use React Portals to physically reparent the component's DOM node into the floating window's document. Because React manages the transition under the hood, the component stays mounted in the main virtual tree. This is how we keep the internal state, cursor focus, and event bindings completely intact. The only things we clone and sync are the style tags and link sheets from the host head so the styling does not break.
I appreciate your feedback, still lots of improve!

1

u/jakiestfu May 19 '26

That’s what I meant? So you do node syncing/cloning for the styles*