π Version 3.x History β
[v3.5.0] - 2026-06-28 β
β¨ What's New β Unified Plugin API β
Tempo v3.5.0 introduces a brand new barrel export for plugin developers: @magmacomputing/tempo/plugin-api.
This new endpoint centralizes all plugin-authoring utilities (defineModule, defineExtension, defineTerm) and internal types into a single location. This architecture significantly cleans up application-level code by formally separating end-user imports from Plugin Developer imports.
If you are developing a custom plugin, you simply update your imports:
// Old Way
// import { defineModule } from '@magmacomputing/tempo/plugin';
// New Way
import { defineModule } from '@magmacomputing/tempo/plugin-api';π Documentation & Ecosystem β
- Static vs Smart CDNs: We have completely overhauled the installation documentation to clarify the distinction between using Smart CDNs (like
esm.shwhich automatically resolve dependencies) for prototyping, versus Static CDNs (with manualimportmapconfigurations) for hardened production environments. - Evergreen Temporal Wording: Removed explicit version claims for upcoming Node.js native
Temporalsupport, future-proofing our guides against shifting V8 release timelines.
[v3.4.0] - 2026-06-26 β
β¨ What's New β Dynamic Format Tokens β
Tempo's formatting engine now supports completely custom format evaluators via the registry.tokens configuration. This allows you to define your own syntax tokens that execute complex math or delegate deeply localized formatting directly to the native Intl API.
Tempo.init({
locale: 'fr-FR',
registry: {
tokens: {
'wkd-fr': (zdt, { config }) => {
const dtOptions = config?.intl?.dateTimeFormat ?? {};
return zdt.toLocaleString(config?.locale ?? 'en', { ...dtOptions, weekday: 'long' });
}
}
}
});
const t = new Tempo('2024-05-20');
t.format('{wkd-fr}'); // "lundi"β¨ Compound Token Modifiers β
The compound date tokens ({dmy}, {mdy}, {ymd}) now support the :yy modifier to easily truncate their internal year components to 2 digits.
t.format('{dmy:yy}'); // "200524"This officially supersedes the legacy *6 tokens (e.g., {dmy6}) which have now been deprecated from documentation to keep the API clean, though they remain fully supported in the engine for backwards compatibility.
[v3.3.1] - 2026-06-22 β
β¨ What's New β Slick Object Mutations β
Tempo has always allowed jumping to boundaries using the Slick Shorthand (#qtr.>2q1) or semantic strings (next Friday). v3.3.1 extends this power directly to .set() object properties.
You can now use SLICK_KEYS (yy, mm, ww, dd, hh, mi, ss, wkd) as object keys in .set(), passing a directional string payload:
const t = new Tempo('2024-05-20'); // Monday
// Jump forward two months
t.set({ mm: '>2' }); // July 20
// Jump to the next Friday
t.set({ wkd: '>Fri' }); // May 24
// "Double-negation" math is fully supported:
t.set({ mm: '<-3' }); // Equivalent to >3This makes relative programmatic date construction cleaner and keeps numeric jumps distinct from absolute assignments.
β‘ Extended Shorthand Modifiers β
The Slick Regex parser has been upgraded to natively support equality logic and aliases. Modifiers like >=, <=, =, + (alias for >), and - (alias for <) are now fully supported for both numeric offsets and semantic loops (like wkd).
// Jump to next Monday, or stay on Monday if today is Monday
t.set({ wkd: '>=Mon' });[v3.3.0] - 2026-06-21 β
β¨ What's New β Localized Modifier Registry β
Tempo's relative-date keywords (next, last, this, ago, hence) were previously hardcoded as English-only constructs built into the core regex engine. v3.3.0 opens this up completely.
You can now register your own locale-specific words for any directional operator using registry.modifiers. These words integrate transparently with all standard parsing paths β prefix position, suffix position, and the high-performance # slick shorthand:
Tempo.init({
locale: 'fr-FR', // teaches Tempo French months & weekdays via Intl
registry: {
modifiers: {
'>': ['prochain', 'suivant'], // "next" synonyms
'<': ['dernier', 'passΓ©'], // "last / previous" synonyms
'=': ['ce', 'cette'], // "this" synonyms
}
}
});
new Tempo('vendredi prochain'); // β
"next Friday" β fully French
new Tempo('1 mai prochain'); // β
"next May 1st"
new Tempo('#qtr.dernier'); // β
"previous quarter" via slick shorthandEnglish keywords (next, last, ago, hence, this) remain active by default and are additively merged β you never lose built-in behaviour when adding your own.
ποΈ Internal Refactoring β
Frozen Default Registry Fixed: The internal
Defaultconfiguration object is wrapped in a deep-freeze Proxy (secure()). Previously, everyTempo.init()call silently failed to writeformats,locales, andmodifiersinto the frozen registry sub-object, logging threesetPropertywarnings per call and abandoning the writes. The registry is now correctly shallow-cloned into a mutable copy on initialization.Lexer Token Cleanup: All hardcoded English modifier keywords have been stripped from the core regex tokens (
Match.modifier,Match.shorthand,Match.slick). The engine now operates purely on symbolic operators (>,<,=,+,-) internally and resolves all natural-language words through the registry at runtime.Pre-filter Guard Accuracy: Refined the numeric-safety guard bypass to trigger only when the input actually contains a registered modifier keyword. Previously the guard was bypassed unconditionally whenever modifier config was present, which could silently accept invalid nanosecond epoch strings.
β‘ Slick Modifier Semantics β
Localized slick modifiers behave identically to their symbolic counterparts. #qtr.prochain is an exact alias for #qtr.>:
- From inside Q2 (any day from April 1 to June 29) β July 1 (start of Q3)
- From June 30 (last day of Q2) β July 1 (start of Q3)
- From July 1 (first day of Q3) β October 1 (start of Q4)
This mirrors how next Friday works: from any non-Friday you get the very next Friday; if you are already on Friday, you get the following Friday. Fully deterministic β "next" always means "the start of the next occurrence of this term".
[v3.2.3] - 2026-06-20 β
β¨ What's New β Project Scaffolding β
tempo.config.tsPattern: Introduced centralized project configuration via a discoverabletempo.config.ts/tempo.config.jsfile. This mirrors thevite.config.ts/tailwind.config.jsconvention β one file, one place, loaded once.Tempo.bootstrap(): A new async entry point that auto-discovers and loads yourtempo.config.tsbefore any domain logic runs. Safe toawaitat application startup.- CLI Scaffold:
npx @magmacomputing/tempo scaffold:allbootstraps atempo.config.tsand HTML sandbox into your project in seconds.
[v3.2.2] - 2026-06-18 β
β¨ What's New β
- Compact Date Tokens: New 6-digit compact format tokens
{dmy6},{mdy6},{ymd6}(e.g.200626), plus ISO week-of-year helpers{yywy}and{yyww}. {wy}Rename: The former{ww}token is now{wy}(week-of-year) to eliminate visual ambiguity with structural format tokens.
ποΈ Internal Refactoring β
- Recursive
deepMergeHardened: The Intl options merge pipeline now uses a fully recursivedeepMergerather than a shallow spread, preventing nested keys likeintl.dateTimeFormatfrom clobberingintl.relativeTimeFormat. - Prototype Pollution Guards: Added strict guards against
__proto__,constructor, andprototypekey assignments indeepMergeanddeepFreezeutilities.
[v3.2.1] - 2026-06-17 β
β¨ What's New β
- Ordinal Localization Fallback: Added support for custom
Intl.PluralRulesdictionaries. By supplying anordinaldictionary inside your globallocalesregistry, Tempo natively evaluates the active plural category (e.g.,'one','other') and appends the localized suffix automatically (such as'1er'and'15e'for French).
π Documentation & Ecosystem β
- Improved Cookbook Ergonomics: Extensively reorganized the
tempo.cookbook.mdto make it easier to read. Related functionality is now logically grouped togetherβfor example, merging native and semantic.add()math examples, and expanding on boundary.set()capabilities. - Clarified Configurations: Updated
tempo.config.mdto remove outdated properties and explicitly document nested options likeintl.durationFormat. - REPL Traps: Added prominent warnings to the documentation about the strict idempotency of
Tempo.init(), helping new developers avoid silent configuration failures in hot-reload and REPL environments.
ποΈ Internal Refactoring β
- Alias Collision Prevention: Hardened the sandbox alias detection engine to prevent redundant collision warnings in the console when
Tempo.initis invoked in sandboxed contexts.
[v3.2.0] - 2026-06-16 β
β¨ What's New β
- Multi-lingual Parsing: The
localeconfiguration property now officially accepts an array of strings (string | string[]). This enables theParseModuleto intelligently extract terminology from multiple languages simultaneously, generating a single engine capable of parsing dates from any of the specified locales interchangeably. - Intl.DateTimeFormatOptions Passthrough: The
.format()method now officially supports passing a nativeIntl.DateTimeFormatOptionsobject. This provides a highly flexible, "humanized" wrapper around the rigidTemporalAPI for complex cultural formatting (e.g., Arabic numerals, Japanese Reiwa eras). - BigInt Overload for Epoch Nanoseconds: The
{nano}formatting token (epoch nanoseconds) correctly coerces to and returns a precision-preservingBigIntinstead of a string, bypassing standardNumberlimits.
π Documentation & Ecosystem β
- Domain-Locked Licensing: Stabilized the premium plugin licensing engine with a robust domain-locked validation mechanism.
- SSR & VitePress Fixes: Fixed
Temporal is not definedcrashes during SSR builds and simplified our documentation pipeline by removing heavy Markdown plugins. - New Locale Guides: Added comprehensive Internationalization (
tempo.locale.md) guides to the primary navigation structure.
ποΈ Internal Refactoring β
- O(1) Locale Traceability: Upgraded the internal dictionary architecture. The Normalizer can now resolve the winning language of a matched token in pure
O(1)time without any expensive Regex sub-capture scanning. - Polyfill Formatting Bypass: Bypassed a known bug in the
Temporalpolyfill'stoLocaleString()method that incorrectly dropped Kanji constraints in Japanese formatting contexts, guaranteeing preciseIntlfallback correctness. - Parser Map Safety: Architecturally split the internal reverse-lookup into distinct
monthMapandweekdayMapdictionaries, eliminating the risk of cross-locale abbreviation collisions (e.g., if "mai" is a month in one language but a weekday in another).
[v3.1.0] - 2026-06-13 β
β¨ What's New β
- Chained Formatting Modifiers: A powerful new format modifier engine (
{mon:locale:upper}) allowing dynamic casing (:upper,:lower), ordinal suffixes (:ord), and deep localization (:locale) dynamically via the nativeIntlAPI. - Auto-Localization Engine: Global configurations for
format: { localize: true }andparse: { localize: true }provide a massive leap forward in out-of-the-box internationalization. Tempo can now intelligently parse localized input (months, weekdays, relative terms like 'demain') and automatically format localized output using memoized, high-performanceIntlstrategies. - Global
localesRegistry: Centralized management for augmenting specific term strings per locale globally across instances viaTempo.init({ locale: 'fr-FR', registry: { locales: { ... } } }).
ποΈ Internal Refactoring β
- Intl Instantiation: Upgraded internal architectures to memoize and pool
Intl.DateTimeFormatobjects seamlessly, ensuring parsing localization generation and output formatting impose virtually zero performance hit on hot execution paths. - Term Localization: Upgraded the Term formatting resolution pipeline to support falling back across a strict precedence: Global Registry > Plugin Bundled Dictionary > term's existing label/value.
[v3.0.0] - 2026-06-08 β
π¨ Major Breaking Changes β
- Term Registry Consolidation: Removed the legacy and deprecated
termproperty from theDiscoveryconfiguration object. All Term-based plugins must now be registered via theterms(plural) array. - Shorthand Configuration Removal: Removed support for shorthand root-level properties in the
Discoveryobject that have been superseded by nested configuration groups:relativeTimeshorthand has been removed; useintl.relativeTimeinstead.termshorthand has been removed; usetermsinstead.
- Strict Parsing Mode: The parser now enforces a stricter
guardcheck by default, reducing the likelihood of "false positive" matches on ambiguous strings. - Ticker Module Extraction: To lighten the core bundle, the
TickerModulehas been extracted into its own standalone premium plugin (@magmacomputing/tempo-plugin-ticker). It is protected by a License Key via the Tempo Registry.
β¨ What's New β
- Formatting Module Additions: Added new compact date tokens (
{dmy},{mdy},{ymd}) for generating 8-digit compact date strings (e.g.24102026).{hhmiss}has been renamed to{hms}for consistency. - Ordinal Tokens: Uppercase variants of standard date tokens (
{DAY},{WW},{MM}) now output their ordinal string representation (e.g.,24th,1st,2nd).
π¦ Migration Path for Tempo.ticker() Users β
If you are upgrading from v2.x and your application relies on Tempo.ticker(), you will need to update your integration:
- Install the Plugin:
npm install @magmacomputing/tempo-plugin-ticker - Activate your License: Obtain your free JWT license key.π Go to the Tempo License Registry π
Manage your subscriptions and retrieve your license key. - Register the Plugin: Wire the key into your application and extend Tempo:javascript
import { Tempo } from '@magmacomputing/tempo'; import { TickerModule } from '@magmacomputing/tempo-plugin-ticker'; Tempo.init({ license: 'YOUR_JWT_KEY' }); Tempo.extend(TickerModule);
ποΈ Internal Refactoring β
- Zero-Fallback Initialization: Cleaned up the
Tempo.init()bootstrap logic to remove legacy compatibility layers, resulting in a cleaner internal state and reduced bundle size. - Build Pipelines: Fully synchronized build pipelines and TS declarations to ensure
vitestandtscoperate seamlessly across local and premium workspaces. - ISO Getter Precision: Upgraded the
.isoproperty getter from nativeDate.toISOString()to Temporal'sInstant.toString(). This provides full ISO 8601 nanosecond precision and conforms to RFC 3339 by gracefully omitting fractional seconds when they evaluate to exactly zero.