npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

barshik-nepali-patro

v1.0.5

Published

A precise, zero-dependency Bikram Sambat (BS) calendar library for React & React Native with official Nepali month data, holiday support, and graceful fallback for future years.

Readme

🇳🇵 barshik-nepali-patro

A precise, zero-dependency Bikram Sambat (BS) calendar library for React and React Native.

Ships with bundled BS month-length tables, public holidays, a holiday details modal, civil-date-safe conversion, graceful fallback for missing future years, and a shared-hook architecture.


📸 UI Preview

Calendar view

Web calendar showing the BS month grid

Holiday details modal

Holiday details modal with full scope and date information


✨ Features

| Feature | Details | |---|---| | Bundled BS Month Data | Month-length tables currently cover BS 2000 → 2100 in months.data.ts so the library can render historical and projected years consistently | | Public Holidays | Holiday tables include nameNp plus scope, so the UI can show both the holiday name and a readable audience/coverage description | | Holiday Details Modal | Clicking or tapping a holiday opens a modal with the full holiday name, Nepali name, BS date, Gregorian date, scope, and any events on that day | | BS ↔ AD Converter | Epoch-based conversion that normalizes to the civil date, avoiding timezone/time-of-day drift | | Graceful Fallback | If a requested year is missing, the library falls back to the latest known year instead of crashing | | Three Entry Points | nepali-patro (web), nepali-patro/native (React Native), nepali-patro/core (utilities only) | | Shared React Hook | useNepaliCalendar drives both web and native UIs — one state layer, two render targets | | Custom Themes | Override colors for Saturdays, holidays, today, selection, event dots, surfaces, borders, and header text | | Event Overlay | Pass arbitrary events such as exams, birthdays, or meetings, with optional custom dot colors | | Tree-Shakeable | Import only what you need; unused UI code is dropped by your bundler |


📦 Installation

npm install barshik-nepali-patro
# or
yarn add barshik-nepali-patro
# or
pnpm add barshik-nepali-patro

Peer dependencies

  • react >= 18.0.0 (required)
  • react-native >= 0.72.0 (optional — only if you use the /native entry)

🚀 Quick Start

1. React (Web)

import { NepaliCalendar } from "barshik-nepali-patro";

function App() {
  return (
    <NepaliCalendar
      events={[
        {
          bsYear: 2083,
          bsMonth: 2,   // Jestha
          bsDay: 15,
          title: "Exam begins",
          color: "#E8751A",
        },
      ]}
      theme={{
        saturdayColor: "#C0272D",
        selectedColor: "#2563EB",
        todayColor: "#E8751A",
      }}
      onDayPress={(day) => {
        console.log("Pressed:", day.bsYear, day.bsMonth, day.bsDay);
        console.log("Holiday scope:", day.holidayScope);
        console.log("AD equivalent:", day.adDate.toISOString());
      }}
      onMonthChange={(year, month) => {
        console.log("Now viewing:", year, month);
      }}
    />
  );
}

Holiday cells open a centered details modal in the calendar UI. The modal shows the full holiday names, scope description, BS date, Gregorian date, and any events attached to that day.

2. React Native

import { NepaliCalendar } from "barshik-nepali-patro/native";

function CalendarScreen() {
  return (
    <NepaliCalendar
      events={[
        {
          bsYear: 2083,
          bsMonth: 1,
          bsDay: 1,
          title: "Nepali New Year",
        },
      ]}
      theme={{ saturdayColor: "#C0272D" }}
      onDayPress={(day) => {
        Alert.alert(
          `${day.bsYear}-${day.bsMonth}-${day.bsDay}`,
          day.holidayName ?? "No holiday"
        );
      }}
    />
  );
}

⚠️ Never import barshik-nepali-patro/native in a web project — it depends on react-native primitives and will crash without the RN runtime.

3. Utilities Only (No UI)

Perfect for backends, CLIs, or custom UI frameworks such as Vue, Svelte, or Angular.

import {
  convertADtoBS,
  convertBStoAD,
  NepaliDate,
  getHolidays,
  generateCalendarGrid,
} from "barshik-nepali-patro/core";

// Convert Gregorian → Bikram Sambat
const bs = convertADtoBS(new Date(2026, 4, 14));
console.log(bs); // { year: 2083, month: 1, day: 31 }

// Convert BS → Gregorian
const ad = convertBStoAD(2083, 1, 31);
console.log(ad); // Date object for 2026-05-14

// Date class with formatting & arithmetic
const d = new NepaliDate(2083, 1, 15);
console.log(d.format("YYYY-MM-DD")); // "2083-01-15"
console.log(d.monthNameNp()); // "बैशाख"
console.log(d.addDays(10).toString()); // "2083-01-25"

// Holidays for a year
const holidays = getHolidays(2082);
console.log(holidays.find((h) => h.month === 1 && h.day === 1));
// { month: 1, day: 1, name: "Nepali New Year", nameNp: "नयाँ वर्ष", scope: "national" }

// Generate a raw calendar grid (weeks × 7 days)
const grid = generateCalendarGrid(2083, 1);
console.log(grid.length); // 5 or 6 weeks

🎨 Theming

All colors accept any valid CSS / React Native color string.

| Token | Default | Applies to | |---|---|---| | saturdayColor | #C0272D | Saturdays + holiday accents | | holidayColor | #C0272D | Holiday accents and modal headings | | eventDotColor | #E8751A | Event indicator dots without an explicit color | | selectedColor | #2563EB | Selected day background | | todayColor | #E8751A | Today ring / highlight | | textColor | #1F2937 | Normal day numbers | | headerColor | #1F2937 | Month/year header text | | surfaceColor | #FFFFFF | Calendar and modal surfaces | | borderColor | #E5E7EB | Calendar grid and modal borders |

<NepaliCalendar
  theme={{
    saturdayColor: "#DC2626",
    selectedColor: "#7C3AED",
    todayColor: "#059669",
    surfaceColor: "#F9FAFB",
    borderColor: "#E5E7EB",
  }}
/>

📐 Architecture

┌─────────────────────────────────────────┐
│  consumer app                           │
│  import from 'barshik-nepali-patro'             │
│  or 'barshik-nepali-patro/native'               │
├─────────────────────────────────────────┤
│  web components    │  native components  │
│  div/span/CSS      │  View/Text/Style     │
│  holiday modal     │  holiday modal       │
├─────────────────────────────────────────┤
│  useNepaliCalendar (shared hook)        │
│  month nav · selected · event merge      │
├─────────────────────────────────────────┤
│  core (pure TypeScript)                 │
│  NepaliDate · converter · generator      │
├─────────────────────────────────────────┤
│  data layer (static)                    │
│  months.data.ts · holidays.data.ts      │
│  fallback.ts (graceful degrade)         │
└─────────────────────────────────────────┘

Why static data instead of formulas? Bikram Sambat month lengths are irregular and are published year by year. The library stores the known tables in code and falls back to the latest known year when future data is missing.


🧪 Testing

The library ships with a comprehensive test suite covering core logic, React hooks, and UI components.

Running Tests

npm test              # Run all tests once
npm run test:watch    # Run tests in watch mode
npm run test:coverage # Run tests with coverage report

Test Structure

All tests live in the test/ directory, mirroring the src/ layout:

test/
├── setup.ts                          # Vitest setup (jest-dom matchers)
├── vitest.d.ts                       # Type declarations for matchers
├── core/
│   ├── converter.test.ts             # BS ↔ AD conversion logic
│   ├── generator.test.ts             # Calendar grid generation
│   └── NepaliDate.test.ts            # Date class behavior
├── data/
│   └── fallback.test.ts              # Graceful fallback resolver
├── hooks/
│   └── useNepaliCalendar.test.ts     # Shared React hook
├── utils/
│   └── formatScope.utils.test.ts     # Holiday scope label formatter
└── components/
    └── web/                          # Web UI components
        ├── DayCell.test.tsx
        ├── Header.test.tsx
        ├── CalendarGrid.test.tsx
        ├── HolidayModal.test.tsx
        └── NepaliCalendar.test.tsx

Test Coverage

| Module | What's tested | |---|---| | converter.ts | BS↔AD conversion, epoch anchor, roundtrip consistency, boundary conditions, timezone normalization | | NepaliDate.ts | Constructor validation, factory methods, formatting tokens, date arithmetic, comparisons, immutability | | generator.ts | 2D grid structure, padding cells, Saturday/holiday flagging, today detection, event merging, year boundary | | fallback.ts | Exact year match, fallback to latest known year, edge cases at data range boundaries | | formatScope.utils.ts | All 11 holiday scope labels, null/undefined handling, unknown scope fallback | | useNepaliCalendar | Initial state, navigation (next/prev/jumpTo), selection management, event handling, grid regeneration | | Web components | Rendering, user interactions, accessibility (ARIA), theme application, event callbacks |

The suite runs 273 tests across 11 test files with a fast Vitest + jsdom setup.


🧩 API Reference

NepaliCalendar Props

| Prop | Type | Default | Description | |---|---|---|---|---| | initialYear | number | Current BS year | Year to open the calendar on | | initialMonth | 1 \| 2 \| … \| 12 | Current BS month | Month to open the calendar on | | events | CalendarEvent[] | [] | Events to overlay | | theme | CalendarTheme | {} | Color overrides | | onDayPress | (day: CalendarDay) => void | — | Called when a day is pressed | | onMonthChange | (year, month) => void | — | Called when month/year changes | | renderDay | RenderDayCallback | — | Override day cell rendering |

renderDay — Custom Cell Rendering

Override the default day cell to add badges, icons, background colors, event titles, or any custom UI.

import { NepaliCalendar } from "barshik-nepali-patro";
import type { RenderDayCallback } from "barshik-nepali-patro";

const renderDay: RenderDayCallback = (day, { isSelected, onPress }) => {
  // Highlight days with events
  if (day.events.length > 0) {
    return (
      <div
        onClick={onPress}
        style={{
          background: isSelected ? "#2563EB" : "#FEF3C7",
          cursor: "pointer",
          padding: 8,
          borderRadius: 4,
          textAlign: "center",
          minHeight: 78,
        }}
      >
        <div>{day.bsDay}</div>
        {day.events.map((e) => (
          <div key={e.title} style={{ fontSize: "0.65rem" }}>{e.title}</div>
        ))}
      </div>
    );
  }
  // Return null to fall back to the default cell for all other days
  return null;
};

<NepaliCalendar renderDay={renderDay} />

The onPress callback preserves built-in behavior (selection toggle + holiday modal + onDayPress). Return null or undefined to fall back to the default DayCell for that day.

Type signature:

type RenderDayCallback = (
  day: CalendarDay,
  defaultProps: { isSelected: boolean; onPress: () => void }
) => React.ReactNode;

HolidayModal

The same modal NepaliCalendar opens internally when a user taps a holiday cell. It is exported from both entry points so you can reuse it anywhere — for example, in a list of the month’s public holidays rendered below the calendar.

React (Web)

import { HolidayModal } from "barshik-nepali-patro";
import type { CalendarDay } from "barshik-nepali-patro";

const [selectedDay, setSelectedDay] = useState<CalendarDay | null>(null);

<HolidayModal
  day={selectedDay}                   // null = hidden, CalendarDay = shown
  onClose={() => setSelectedDay(null)}
  theme={{ holidayColor: "#C0272D" }} // optional — same tokens as NepaliCalendar
/>

React Native

import { HolidayModal } from "barshik-nepali-patro/native";
import type { CalendarDay } from "barshik-nepali-patro/native";

const [selectedDay, setSelectedDay] = useState<CalendarDay | null>(null);

<HolidayModal
  day={selectedDay}
  onClose={() => setSelectedDay(null)}
  theme={{ holidayColor: "#C0272D" }}
/>

The web and native versions share identical props but render with their own platform primitives. Never import barshik-nepali-patro/native in a web project or vice versa.

Props (same for both platforms)

| Prop | Type | Required | Description | |---|---|---|---| | day | CalendarDay \| null | ✅ | The day to display. Pass null to close. | | onClose | () => void | ✅ | Called when backdrop or × is pressed. | | theme | CalendarTheme | — | Same theme object as NepaliCalendar. |

There is no visible prop. Visibility is derived from !!day. Pass null to close — do not pass a separate boolean.

Building a CalendarDay from a NepaliHoliday

When you have a NepaliHoliday from getHolidays() and want to open the modal from your own list, construct the CalendarDay manually:

import { convertBStoAD } from "barshik-nepali-patro/core";
import type { CalendarDay, NepaliHoliday } from "barshik-nepali-patro"; // or /native

function holidayToDay(h: NepaliHoliday, year: number, month: number): CalendarDay {
  const adDate = convertBStoAD(year, month, h.day);
  return {
    bsDay: h.day,
    bsMonth: month,
    bsYear: year,
    adDate,
    isSaturday: adDate.getDay() === 6,
    isHoliday: true,
    holidayName: h.name,
    holidayNameNp: h.nameNp,
    holidayScope: h.scope,
    isToday: false,
    isCurrentMonth: true,
    events: [],
  };
}

CalendarEvent

interface CalendarEvent {
  bsYear: number;
  bsMonth: 1 | 2 | ... | 12;
  bsDay: number;
  title: string;
  color?: string; // optional dot color
}

NepaliHoliday

interface NepaliHoliday {
  month: number;
  day: number;
  name: string;
  nameNp?: string;
  scope?: HolidayScope;
}

HolidayScope

The holiday details modal displays a readable description for each scope.

| Scope | Meaning | |---|---| | national | Observed nationwide | | dashain | Dashain festival holiday | | tihar | Tihar festival holiday | | ethnic | Holiday for specific ethnic communities | | women | Holiday for women only | | education | For educational institutions only | | kathmandu-valley | Only inside Kathmandu Valley | | observed | Officially observed holiday | | disabilities | For people with disabilities | | birth-anniversary | Commemorates a birth anniversary | | office-open | Government offices remain open |

CalendarDay

interface CalendarDay {
  bsDay: number;
  bsMonth: BSMonth;
  bsYear: BSYear;
  adDate: Date;              // Gregorian equivalent
  isSaturday: boolean;
  isHoliday: boolean;        // true if public holiday OR Saturday
  holidayName?: string;      // English holiday label
  holidayNameNp?: string;    // Devanagari holiday label
  holidayScope?: HolidayScope; // Holiday audience/category from the source data
  isToday: boolean;
  isCurrentMonth: boolean;   // false for padding days
  events: CalendarEvent[];
}

useNepaliCalendar Hook

For advanced consumers who want to build a custom UI while reusing the shared calendar state.

import { useNepaliCalendar } from "barshik-nepali-patro";

const {
  year,
  month,
  grid,          // CalendarDay[][]
  selected,
  setSelected,
  holidays,
  events,
  goNextMonth,
  goPrevMonth,
  jumpTo,
  goToday,
  isCurrentMonth,
} = useNepaliCalendar({
  initialYear: 2083,
  initialMonth: 1,
  events: myEvents,
});

NepaliDate Class

const d = new NepaliDate(2083, 1, 15);

d.toAD();               // → Date (Gregorian)
d.format("YYYY-MM-DD"); // → "2083-01-15"
d.monthNameNp();        // → "बैशाख"
d.addDays(10);          // → new NepaliDate(...)
d.addMonths(2);         // → new NepaliDate(...)
d.isBefore(other);      // → boolean
d.equals(other);        // → boolean
NepaliDate.today();     // → NepaliDate for today
NepaliDate.fromAD(ad);  // → NepaliDate from JS Date

🗓️ Adding New Year Data

When the Nepal government publishes the official calendar for a new BS year:

  1. Month lengths — open src/data/months.data.ts and append the year:

    2091: [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
  2. Holidays — open src/data/holidays.data.ts and append the year:

    2091: [
      { month: 1, day: 1, name: "Nepali New Year", nameNp: "नयाँ वर्ष", scope: "national" },
      // ...rest of the official list
    ],
  3. No code changes needed — the fallback resolver automatically picks up the new year.

  4. Open a PR with a link to the official gazette / Nepal Calendar Determination Committee announcement.


🤝 Contributing

We welcome contributions. Typical PRs include:

  • Data updates — new BS year tables or corrected holidays.
  • Bug fixes — converter edge cases, UI glitches, accessibility improvements.
  • Features — new theme tokens, additional date formatting tokens, or UI polish.

Development setup

git clone https://github.com/Abhishek-Gaire/nepali-patro.git
cd nepali-patro
npm install
npm run typecheck
npm test
npm run build

Please include tests for any core logic changes and follow the existing comment style. Test files live in the test/ directory and follow the same layout as src/.


📄 License

MIT © Abhishek Gaire


🙏 Acknowledgements

  • Month-length data sourced from official publications of the Nepal Calendar Determination Committee (नेपाल पञ्चाङ्ग निर्णायक समिति) and maintained year tables in the repository.
  • Holiday lists based on Government of Nepal public holiday notifications.