Chronos Plugins
- 
Chronossupports a powerful plugin system that allows developers to inject additional methods or utilities into theChronosclass without modifying its core. This enables clean separation of concerns, tree-shaking, modular feature design, and maintainability. - 
Plugins can be official (maintained by the core team) or custom (developed by users). See the list of official plugins below or learn how to write your own plugin.
 
π§© What Is a Plugin?β
A plugin is a function that takes the Chronos class constructor and augments itβusually by adding prototype methods.
type ChronosPlugin = (ChronosClass: typeof Chronos) => void;
You can inject plugins via the static Chronos.use() method or its wrapper function:
Chronos.use(pluginName);
// or 
chronos.use(pluginName)
- Each plugin is only applied once, even if 
use()is called multiple times with the same plugin. - If a plugin enables multiple methods, injecting once will enable all the methods by that particular plugin. See the list below
 
β Using a Pluginβ
To enable a plugin, use the static Chronos.use() method before creating instances:
import { Chronos, chronos } from 'nhb-toolbox';
// For importing a plugin from the package, plugin name and import path are same
import { pluginName } from 'nhb-toolbox/plugins/pluginName';
// Using the plugin
Chronos.use(pluginName);
// or 
chronos.use(pluginName)
// Using the method enabled by that plugin
const c = new Chronos();
c.enabledMethod();
// or 
chronos().enabledMethod()
π¦ Official Pluginsβ
| Plugin Names | Imports Statements | Methods Registered | 
|---|---|---|
relativeTimePlugin | getRelativeYear, getRelativeMonth, getRelativeWeek, getRelativeDay, getRelativeHour, getRelativeMinute, getRelativeSecond, getRelativeMilliSecond, compare, isToday, isTomorrow, isYesterday | |
timeZonePlugin | timeZone, getTimeZoneName, getTimeZoneNameShort | |
fromNowPlugin | fromNow | |
businessPlugin | isWeekend, isWorkday, isBusinessHour, toAcademicYear, toFiscalQuarter | |
seasonPlugin | season | |
dayPartPlugin | getPartOfDay | |
zodiacPlugin | getZodiacSign | |
palindromePlugin | isPalindromeDate | |
greetingPlugin | getGreeting | |
roundPlugin | round | |
| (More coming soon) | 
π οΈ Writing Your Own Custom Pluginβ
Here's the basic structure of a Chronos plugin with access to protected and/or private internals:
import { Chronos, INTERNALS } from 'nhb-toolbox';
// Create a module augmentation to add your custom method to the `Chronos` interface
// This allows TypeScript to recognize the new method on `Chronos` instances
// This should be inside a `d.ts` file or at the top of your plugin file (must be a `.ts` file)
declare module 'nhb-toolbox/chronos' {
  interface Chronos {
    /**
    * @instance Custom `Chronos` method to greet a user with the current date.
    * @param user The name of the user to greet.
    * @returns A greeting message including the user's name and the current ISO dates.
    */
    customMethod(user: string): string;
  }
}
// The plugin function must be in a `.ts` or `.js` file
/** * Plugin to inject `customMethod` into Chronos instances. */
export const customPlugin = (ChronosClass: typeof Chronos): void => {
  ChronosClass.prototype.customMethod = function (this: Chronos, user: string): string {
    // Example of accessing internals through protected static interface
    const internalDate = ChronosClass[INTERNALS].internalDate(this);
    return `Hello ${user}, Welcome to custom plugin! Current date: { local: ${this} } { utc: ${internalDate.toISOString()} }`;
  };
};
Now consume the plugin in the same file or another file where you want to use your custom method
import { Chronos } from 'nhb-toolbox';
// or import { Chronos } from 'nhb-toolbox/chronos';
import { customPlugin } from './path-to-your-plugin-file';
// Use the plugin in your application's root/entry file or where you initialize `Chronos`
Chronos.use(customPlugin);
new Chronos().customMethod('NHB');
// => "Hello NHB, Welcome to custom plugin! Current date: { local: 2025-09-22T14:47:44.132+06:00 } { utc: 2025-09-22T08:47:44.132Z }"
π Accessing Internalsβ
Plugins can safely access protected and/or private internal properties or methods through the static [INTERNALS] interface:
π Available Internal Propertiesβ
interface ChronosInternals {
  /**
   * Creates a new Chronos instance with origin tracking
   * @param instance - Chronos instance to operate on
   * @param method - Name of the method creating this instance
   * @param label - Optional UTC offset label
   */
  withOrigin(
    instance: Chronos,
    method: ChronosMethods,
    label?: UTCOffSet,
  ): Chronos;
  /**
   * Creates a new Date object from Chronos input
   * @param instance - Chronos instance to operate on
   * @param value - Input value to convert (optional, uses current date if omitted)
   */
  toNewDate(instance: Chronos, value?: ChronosInput): Date;
  /**
   * Gets the internal Date object
   * @param instance - Chronos instance to access
   */
  internalDate(instance: Chronos): Date;
  /**
   * Gets the current UTC offset
   * @param instance - Chronos instance to access
   */
  offset(instance: Chronos): UTCOffSet;
}
π Usage Exampleβ
Here's a real example from the package itself: plugin that adds a
timeZonemethod toChronosinstances, allowing users to convert the instance to a specified time zone using some internal methods and properties:
import { Chronos, INTERNALS } from 'nhb-toolbox';
// Other imports
declare module 'nhb-toolbox/chronos' {
  interface Chronos {
    timeZone(): string;
  }
}
export const timeZonePlugin = (ChronosClass: typeof Chronos): void => {
  ChronosClass.prototype.timeZone = function (
    this: Chronos,
    zone: TimeZone | UTCOffSet
  ): Chronos {
    let targetOffset: number;
    let stringOffset: UTCOffSet;
    if (isValidUTCOffSet(zone)) {
      targetOffset = extractMinutesFromUTC(zone);
      stringOffset = zone;
    } else {
      targetOffset = TIME_ZONES?.[zone] ?? TIME_ZONES['UTC'];
      stringOffset = formatUTCOffset(targetOffset);
    }
    const previousOffset = this.getTimeZoneOffsetMinutes();
    const relativeOffset = targetOffset - previousOffset;
    const internals = ChronosClass[INTERNALS];
    const adjustedTime = new Date(
      internals.internalDate(this).getTime() + relativeOffset * 60 * 1000
    );
    const instance = new ChronosClass(adjustedTime);
    return internals.withOrigin(instance, 'timeZone', stringOffset);
  };
};
π₯ Important Notesβ
- Always augment 
Chronosvia module augmentation to ensure TypeScript recognizes your new methods using this subpath:'nhb-toolbox/chronos' - Import 
ChronosandINTERNALSfrom'nhb-toolbox'in your plugin file - Always use the static 
[INTERNALS]interface rather than trying to access private fields directly - The 
withOriginmethod should be used when creating newChronosinstances to maintain proper origin tracking - For native js 
Datemanipulation in your plugin, prefer usingtoNewDatefromChronosInternalsinterface rather than creatingDateobjects directly to maintain consistency with internal handling ofChronos