Repo of the Day
kapeka0/react-pinote
Published: Sep 10, 2026
Open repository ↗Lightweight annotations for your React UI
Summary
react-pinote is a small TypeScript library that adds hover-to-preview annotations to React UIs. It ships components for element-level, text, and coordinate-based notes and works with React 18, React 19, and shadcn/ui. The runtime footprint is limited to React and React DOM, so it fits into existing projects without pulling in extra UI frameworks.
What it is useful for
The library helps engineers drop review-style notes directly onto a running UI. Typical use cases include:
- Design and content review: attach a comment to a heading, button, or paragraph without leaving the page.
- QA and bug reporting: highlight a specific phrase or element so a teammate can see exactly what needs changing.
- Coordinate-based feedback: place free-floating notes on a canvas, mockup, or any region by drag-and-drop position using
PinoteLayer. - Embedded documentation: pin short hints or onboarding tips to specific UI regions.
Because the content prop accepts any React node, the same note can carry plain text, a form, a link, or a richer component. According to the README, Pinote handles positioning, motion, and focus, while the host app owns the storage and lifecycle of each note, which makes it straightforward to back with local state, an API, or a real-time collaboration layer.
How engineers can use it
Installation is the npm command documented in the README:
npm i react-pinote
Wrap the relevant part of the tree in PinoteProvider, then attach a Pinote to the target element with a unique id and a content prop:
import { Pinote, PinoteProvider } from "react-pinote";
export default function App() {
return (
<PinoteProvider>
<Pinote id="heading" content="Could this heading be shorter?">
<h1>Get started</h1>
</Pinote>
</PinoteProvider>
);
}
For text-level annotations, use PinoteHighlight. For draggable, coordinate-placed notes, use PinoteLayer. The provider adds no extra HTML wrapper, and only one note stays open at a time, so layout shifts are minimal.
Documented behaviors to keep in mind: each note must have a unique id within its PinoteProvider, and only one note is open at a time, which is a deliberate design choice noted in the README. Framework-specific setup for Next.js, Astro, Tailwind, and shadcn/ui dark mode lives in the framework docs, styling docs, and API reference, which the README points to for those steps.