Modules
Modules extend Messagevisor runtime behavior without changing the datafile schema. They are the main way syntax and formatting logic becomes active at evaluation time.
What modules are for#
Modules can influence:
- message syntax handling
- interpolation
- formatting behavior
- rich text transformation
- custom diagnostics and observability
- feature flag or experiment resolver integration
- per-call module options
Where modules matter#
Modules affect more than application runtime. They also affect:
- CLI
evaluate examples- locale tests
- target tests
- catalog example output
This is an important point: if a message or raw string behaves differently than expected, modules are often part of the reason.
How modules are configured#
Register them in messagevisor.config.js:
const { createICUModule } = require("@messagevisor/module-icu");const { createInterpolationModule } = require("@messagevisor/module-interpolation");const { createFeaturevisorModule } = require("@messagevisor/module-featurevisor");const { createMissingTranslationsModule } = require("@messagevisor/module-missing-translations");const { createInstance } = require("@featurevisor/sdk");const f = createInstance({ datafile: require("./featurevisor-datafile.json"),});module.exports = { modules: [ createInterpolationModule(), createICUModule(), createFeaturevisorModule({ instance: f }), createMissingTranslationsModule({ handler({ messageKey, locale }) { console.warn("Missing translation", { messageKey, locale }); }, }), ],};Register equivalent modules on SDK instances that run inside applications. Project config powers CLI workflows; runtime SDK setup powers the app.
Ordering matters when multiple modules transform the same string.
Available modules in this repo#
You can also write your own modules. See Custom modules for the full module contract, lifecycle, and examples.
Use the Featurevisor module when you want feature and experiment conditions in Messagevisor to resolve against an existing Featurevisor SDK instance.
Use the Missing translations module when you want missing translation diagnostics to flow into your own logging, analytics, or developer tooling.
Module ordering#
If more than one module participates, think about composition order.
For example:
- interpolation before ICU
- ICU before a post-processing transform
The correct order depends on what syntax is present in your messages.
Per-call module options#
Evaluation methods can also pass moduleOptions.
This is useful when:
- one call needs different rich-text handling
- one test should ignore tags
- one rendering path needs a module-specific escape hatch
Options are keyed by module name, so a module named icu reads from moduleOptions.icu.
Writing custom modules#
Custom modules can implement any combination of:
setupfor registration-time workformatfor interpolation and syntax handlingtransformfor final output post-processingclosefor cleanup
Use modules for behavior that changes evaluated output or runtime evaluation. Use plugins for CLI workflows and parsers for authoring file formats.
Edge cases and behavior notes#
Formats are not the same as modules#
Locale formats define named Intl-shaped presets.
Modules decide how a message string uses those presets and how syntax is interpreted.
A valid message file can still evaluate differently after a module change#
That is expected. Modules are part of runtime behavior, not just authoring decoration.

