Install, CSS imports, and a minimal working snippet — everything you need to render a live picker in under five minutes.
npm install @cyberlz/react-date-rangeRequires react@^18.0.0 || ^19.0.0, react-dom@^18.0.0 || ^19.0.0, and date-fns@^3.0.0.
Add both CSS files before any component code. Place them once, above the fold (e.g. in index.html or your root layout).
@import "@cyberlz/react-date-range/styles.css";
@import "@cyberlz/react-date-range/theme/default.css";Or as JavaScript imports at your app entry point:
import '@cyberlz/react-date-range/styles.css';
import '@cyberlz/react-date-range/theme/default.css';Both are required. styles.css provides the structural layout; theme/default.css provides the default visual theme.
Import theme/variables.css when you want CSS custom-property overrides. It is not imported by the default styles, so existing apps keep their current output unless they opt in.
import '@cyberlz/react-date-range/styles.css';
import '@cyberlz/react-date-range/theme/default.css';
import '@cyberlz/react-date-range/theme/variables.css';Override CSS variables on any ancestor of the picker:
<div style={{ '--rdr-color-primary': '#7c3aed' }}>
<DateRangePicker ranges={ranges} onChange={setNextRanges} />
</div>Available variables are colors (primary, on-primary, surface, on-surface, muted, border, today), spacing (xs, sm, md, lg), and radius (sm, md) using the --rdr-{color|space|radius}-{name} naming pattern.
All exports are named — no default export. Import only what you use.
import { Calendar } from '@cyberlz/react-date-range';
import { DateRange } from '@cyberlz/react-date-range';
import { DateRangePicker } from '@cyberlz/react-date-range';
import { DefinedRange } from '@cyberlz/react-date-range';
import { DatePickerInput } from '@cyberlz/react-date-range';
import { DateRangeInput } from '@cyberlz/react-date-range';Do not import the default export — it does not exist.
Calendar is fully SSR-safe.
DateRange and DateRangePicker render a stable picker surface on the server. DatePickerInput and DateRangeInput guard browser API access (window/document) with typeof-of-undefined checks. None of these components require ssr: false by default.
If you encounter hydration mismatches with input components, the likely cause is open/closed popover state differing between server and client renders. Keep popover state closed initially (defaultOpen={false} or open={false}) and let user interaction or client-side hydration drive the first open.
For SSR frameworks with known hydration issues, dynamic import with ssr: false is a practical workaround:
// Next.js (pages router)
import dynamic from 'next/dynamic';
const DateRangePicker = dynamic(
() => import('@cyberlz/react-date-range').then((m) => m.DateRangePicker),
{ ssr: false }
);For server-rendered static pages, Calendar renders without popover chrome.
import * as React from 'react';
import { DateRangePicker } from '@cyberlz/react-date-range';
import '@cyberlz/react-date-range/styles.css';
import '@cyberlz/react-date-range/theme/default.css';
function App() {
const [ranges, setRanges] = React.useState([
{ startDate: new Date(), endDate: new Date(), key: 'selection' },
]);
return (
<DateRangePicker
ranges={ranges}
onChange={(rangesByKey) => setRanges([rangesByKey.selection])}
/>
);
}This renders a controlled range picker. For the full controlled-state pattern, see docs/integrations/controlled-state.md.
- Full evaluation guide:
docs/evaluation-guide.md - Component reference:
docs/components/README.md - Migration from upstream:
docs/migration-from-upstream.md