@rehookify/datepicker

Headless React hooks for building fully custom date, range, and time pickers with zero dependencies.

Library
npm
v6.6.8
338stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
45/100Fair
Development Activity0
Maintenance48
Community52
Maturity52
Momentum28

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
77/100Good
Architecture82
Code Quality85
Innovation72
Learning Curve70

@rehookify/datepicker is a headless React hook library for building date, range, and time pickers without shipping any pre-styled UI. Instead of a fixed component, it exposes a set of modular hooks and prop-getters that hand back the state and DOM props needed to render calendars, day grids, month/year selectors, and time inputs however the consuming application wants them styled.

The library follows the prop-getters convention popularized by headless UI libraries like Downshift, applying it specifically to the date-picker domain. Consumers compose only the hooks they need (useDays, useMonths, useYears, useTime, useCalendars) rather than pulling in a single monolithic component, which keeps bundle size small and avoids forcing a particular markup or design system on the caller.

It has no runtime dependencies of its own, relies on native Intl APIs for locale-aware date and time formatting instead of a heavy date library, and supports single, multiple, and range selection modes alongside multi-calendar layouts and configurable time pickers.

What You Get

  • A useDatePicker hook combining calendar, day, month, year, and time state into one call, plus standalone hooks for each concern if you only need part of the behavior
  • Prop-getters (dayButton, addOffset, subtractOffset, nextYearsButton, and more) that return ready-to-spread DOM props including click handlers, disabled state, and ARIA attributes
  • Built-in support for single, multiple, and range date-selection modes, plus an independent time picker with configurable interval and min/max limits
  • Multi-calendar (side-by-side month) rendering support driven by configurable offsets
  • Native Intl.DateTimeFormat/toLocaleDateString locale support instead of bundling a separate date-formatting dependency
  • Zero runtime dependencies, published as CJS, ESM, and UMD builds with TypeScript type definitions

Common Use Cases

  • Building a fully custom-styled date picker input that matches an existing design system instead of overriding a pre-built component’s CSS
  • Adding a date-range picker to booking, scheduling, or reservation UIs where start/end selection and range-length limits matter
  • Building a combined date-and-time picker for appointment or event-creation forms
  • Rendering a multi-month calendar view (e.g. two months side by side) for range selection
  • Replacing a heavier third-party date-picker component to reduce bundle size in a performance-sensitive app

Under The Hood

Architecture The library centers on useDatePickerState (packages/datepicker/src/use-date-picker-state.ts), which normalizes user config via createConfig and drives a small useReducer-based state machine (state-reducer.ts) with four actions — SET_FOCUS_DATE, SET_OFFSET_DATE, SET_RANGE_END, SET_YEAR — exposed through typed dispatch helpers (setFocus, setOffset, setRangeEnd, setYear) rather than raw dispatch calls. The top-level useDatePicker hook (use-date-picker.ts) composes this shared state into independent domain hooks (useCalendars, useDays, useMonths, useTime, useYears), each returning both derived data and DOM-ready propGetters; every prop-getter is itself built from one shared createPropGetter utility (utils/create-prop-getter.ts) that encodes the disabled/onClick/aria-selected prop shape once. This layering means a consumer can import just useDays or useYears instead of the combined hook, and a change to the shared prop-getter shape only needs to happen in one place.

Tech Stack Written entirely in TypeScript with React 16.8+/17/18/19 as a peer dependency and zero runtime dependencies of its own. The package build uses Rollup (rollup-plugin-typescript2, rollup-plugin-peer-deps-external, @rollup/plugin-terser) to emit CJS, ESM, and UMD bundles plus .d.ts type definitions, while the pnpm workspace root manages a monorepo of three packages (the library, an examples app, and an examples-e2e Playwright suite). Date/time formatting relies on native Intl.DateTimeFormat and toLocaleDateString/toLocaleTimeString rather than an external date library.

Code Quality The library ships 26 Vitest test files covering the reducer, every domain hook, and the pure utility functions (create-time, create-years, create-calendars, get-date-range-state, predicates, offset, config, excluded), using @testing-library/react’s renderHook/act pattern against real hook output rather than mocked internals. Typing is pervasive — a dedicated types/ directory defines the full public contract (DPState, DPConfig, DPUseDatePicker, DPPropGetter, etc.) that the hooks implement against. ESLint (typescript-eslint, eslint-plugin-react, react-hooks, simple-import-sort) plus Prettier are enforced through a Husky pre-commit hook via lint-staged, and GitHub Actions runs separate unit.yml and e2e.yml workflows. One edge-case test (min/max date boundaries) is explicitly marked .skip, and there is no visible coverage-reporting step in CI.

What Makes It Unique Most date-picker libraries in the React ecosystem ship a single styled component; this one applies the prop-getters/headless pattern familiar from libraries like Downshift specifically to calendars, ranges, and time pickers, and goes further by splitting even that headless logic into independently importable hooks per concern (days vs. months vs. years vs. time) so unused code paths don’t ship. Combined with zero runtime dependencies and reliance on native Intl formatting instead of a bundled date library, it trades a small amount of setup convenience for a notably smaller and more flexible footprint than typical alternatives.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search