A collection of production-ready React hooks for common UI patterns.
npm install @3ni8ma/react-hooksReactive media query matching.
import { useMediaQuery } from '@3ni8ma/react-hooks'
function Component() {
const isMobile = useMediaQuery('(max-width: 768px)')
const isDark = useMediaQuery('(prefers-color-scheme: dark)')
return <div>{isMobile ? 'Mobile' : 'Desktop'}</div>
}Copy text to clipboard with feedback state.
import { useClipboard } from '@3ni8ma/react-hooks'
function CopyButton({ text }) {
const { copy, copied } = useClipboard()
return <button onClick={() => copy(text)}>{copied ? 'Copied!' : 'Copy'}</button>
}Debounce a rapidly changing value.
import { useDebounce } from '@3ni8ma/react-hooks'
function Search() {
const [query, setQuery] = useState('')
const debouncedQuery = useDebounce(query, 300)
// debouncedQuery updates 300ms after last change
}Persist state to localStorage with type safety.
import { useLocalStorage } from '@3ni8ma/react-hooks'
function Settings() {
const [theme, setTheme] = useLocalStorage('theme', 'light')
return <select value={theme} onChange={e => setTheme(e.target.value)} />
}Observe element visibility for lazy loading or animations.
import { useIntersectionObserver } from '@3ni8ma/react-hooks'
function LazyImage({ src }) {
const { ref, isIntersecting } = useIntersectionObserver({ threshold: 0.1 })
return <div ref={ref}>{isIntersecting && <img src={src} />}</div>
}Simple boolean toggle with convenience methods.
import { useToggle } from '@3ni8ma/react-hooks'
function Accordion() {
const { value: open, toggle, setTrue, setFalse } = useToggle(false)
return <div>{open && <div>Content</div>}</div>
}Track browser online/offline status.
import { useOnlineStatus } from '@3ni8ma/react-hooks'
function NetworkStatus() {
const isOnline = useOnlineStatus()
return <div>{isOnline ? 'Online' : 'Offline'}</div>
}Set document.title reactively with automatic cleanup.
import { useDocumentTitle } from '@3ni8ma/react-hooks'
function ProfilePage({ name }) {
useDocumentTitle(`${name} — My App`)
return <div>Profile</div>
// title restores when component unmounts
}MIT