Skip to content

Plugin System

Atemporal has a lightweight plugin system that allows you to extend its functionality only when needed, keeping the core bundle small.

How to Use Plugins

Standard Extension

Import the plugin and extend atemporal using atemporal.extend().

ts
import atemporal from "atemporal";
import relativeTime from "atemporal/plugins/relativeTime";

atemporal.extend(relativeTime);

// Now you can use .fromNow()
atemporal().subtract(5, "m").fromNow();

Plugins can optionally accept configuration options:

ts
atemporal.extend(relativeTime, { threshold: 45 });

Lazy Loading

To reduce the initial bundle size, you can load plugins on demand. Atemporal provides robust lazy-loading utilities that dynamically import plugins when requested.

ts
import atemporal from "atemporal";

// Load a single plugin
async function showRelativeTime() {
  await atemporal.lazyLoad("relativeTime");

  const twoHoursAgo = atemporal().subtract(2, "hour");
  console.log(twoHoursAgo.fromNow()); // "2 hours ago"
}

// Load multiple plugins at once
async function loadAdvancedFeatures() {
  await atemporal.lazyLoadMultiple(["businessDays", "timeSlots"]);
}

// Pass options to lazy-loaded plugins
await atemporal.lazyLoadMultiple(["weekDay", "customParseFormat"], {
  weekDay: { defaultWeekStart: 1 },
});

Plugin Utilities

You can query the state of plugins at runtime using the following utilities:

ts
// Check if a specific plugin is loaded
const hasRelativeTime = atemporal.isPluginLoaded("relativeTime");

// View an array of all currently loaded plugins
const loaded = atemporal.getLoadedPlugins();

// View all available plugins that can be lazy-loaded
const available = atemporal.getAvailablePlugins();

Available Plugins

Creating Your Own Plugin

Atemporal's plugin system is designed to be extensible. You can create custom plugins using the Plugin type signature.

Plugin Type Signature

ts
type Plugin = (
  Atemporal: typeof TemporalWrapper,  // The TemporalWrapper class
  atemporal: AtemporalFactory,        // The factory function with all static methods
  options?: any                       // Optional configuration
) => void;

Basic Plugin Example

ts
import atemporal, { type Plugin, markAsPlugin } from "atemporal";

const myPlugin: Plugin = (Atemporal, atemporal, options) => {
  // Add instance methods to the prototype
  Atemporal.prototype.isMorning = function () {
    return this.hour < 12;
  };

  // Add static methods to the factory
  (atemporal as any).greet = function (name: string) {
    return `Hello, ${name}! The time is ${atemporal().format("HH:mm")}`;
  };
};

// Mark it as a valid atemporal plugin (required for isPlugin() detection)
markAsPlugin(myPlugin);

// Register it
atemporal.extend(myPlugin, { /* optional config */ });

// Now use your custom methods
const now = atemporal();
console.log(now.isMorning()); // true or false
console.log(atemporal.greet("World")); // "Hello, World! The time is 10:30"

Plugin Detection

Plugins marked with markAsPlugin() are identifiable:

ts
import { markAsPlugin, PLUGIN_SENTINEL } from "atemporal";

const myPlugin = markAsPlugin((Atemporal, atemporal) => {
  // ...
});

atemporal.isPlugin(myPlugin); // true

// The PLUGIN_SENTINEL symbol is used internally for plugin identification
console.log((myPlugin as any)[PLUGIN_SENTINEL]); // true