Providers
Providers are the runtime components that supply format and unit definitions to formatters and parsers. Understanding the different provider types and how to register them is essential for setting up quantity formatting in iTwin.js applications.
Understanding Providers
UnitsProvider
The UnitsProvider interface is central to unit management in iTwin.js. It provides methods to:
- Locate units by name or label
- Retrieve UnitProps for a given unit
- Generate UnitConversionSpec objects for converting between units
Units Provider Concept
A units provider acts as a registry and converter for units. When you need to format or parse a quantity value, the provider:
- Locates the source unit (e.g., meters for persistence)
- Locates the target unit (e.g., feet and inches for display)
- Provides conversion factors between these units
- Validates unit compatibility (ensures units are in the same phenomenon)
BasicUnitsProvider
BasicUnitsProvider is a standalone provider backed by the full BIS Units schema bundled as a JSON asset in @itwin/core-quantity. It is the default provider used by IModelApp.quantityFormatter when no iModel-specific provider is registered.
Characteristics:
- No dependencies on iModels or schemas — works in any context (frontend, backend, tools)
- Contains all BIS units covering all phenomena (length, area, volume, temperature, pressure, angle, force, velocity, etc.)
- Unit data is resolved lazily on first use and cached at module scope — construction is essentially free, and multiple instances share the same immutable lookup indexes
- Available from
@itwin/core-quantity, so it can be used outside@itwin/core-frontend - The bundled unit data is versioned:
versiontracks the serialization format, andsourceEcSchemaVersionrecords which BIS Units EC schema release the data was derived from
When to use:
- Default for all applications — enabled automatically by
QuantityFormatter - Backend or CLI tools that need unit resolution without an iModel
- UIs and workflows that don't need an iModel, like iTwin-level workflows
- As a lightweight alternative to
SchemaUnitProviderwhen domain-specific custom units are not needed
Note: The
BasicUnitsProviderpreviously exported from@itwin/core-frontendwas a limited provider (≈40 units) and has been removed. Use BasicUnitsProvider from@itwin/core-quantityinstead.
Synchronous local data
Use the optional SyncUnitsProvider capability when a caller must construct a formatter without awaiting a provider. BasicUnitsProvider implements it for the bundled canonical BIS units.
These methods use local data only. BasicUnitsProvider returns BadUnit for an unknown name. It returns an identity conversion with error: true when a unit is unavailable or the units are incompatible. Treat either result as a miss and use the plain-value fallback instead of loading a schema or awaiting.
A format provider can implement SyncFormatsProvider when it can return a locally available FormatDefinition through getFormatSync. The method returns undefined when the format is not available synchronously; it does not make schema loading synchronous. A provider that delegates the current lookup to another provider should forward the optional lookup context unchanged; omit it only when starting an independent lookup.
createUnitsProvider
createUnitsProvider is a factory function that layers a primary provider (such as SchemaUnitProvider) on top of BasicUnitsProvider. Schema-defined units win on overlap; basic BIS units fill any gaps. Pass bisUnitsPolicy: "preferBundled" to invert precedence so the bundled BIS units win instead.
When no primary is supplied, createUnitsProvider() returns a plain new BasicUnitsProvider() — no wrapper.
You can also use the generated canonical identifiers exported by @itwin/core-quantity to avoid magic strings when looking up bundled BIS units:
When you need a recommended built-in persistence unit for a bundled phenomenon, use getDefaultPersistenceUnit. For example, getDefaultPersistenceUnit(Phenomena.LENGTH) returns Units.LENGTH.M.
Note:
getDefaultPersistenceUnit(...)intentionally does not acceptPhenomena.LENGTH_RATIOyet, because the bundled built-in unit set does not currently provide an agreed default for that phenomenon.
SchemaUnitProvider
SchemaUnitProvider loads unit definitions from EC schemas using a SchemaContext. It provides access to the extensive Units schema as well as custom units defined in domain schemas.
Characteristics:
- Requires access to ECSchemas via SchemaContext, commonly through iModels
- Accesses units through SchemaContext
- Supports custom domain-specific units not included in the bundled BIS
Unitsschema
When to use:
- Applications working with iModels
- When domain-specific units (civil, structural, etc.) are needed
- When unit definitions must match schema specifications
FormatsProvider
A FormatsProvider supplies format definitions for a KindOfQuantity. The FormatDefinition interface extends FormatProps to help identify formats.
SchemaFormatsProvider
SchemaFormatsProvider retrieves formats from EC schemas using a SchemaContext. An optional UnitSystemKey selects formats for a unit system.
A schema-backed provider can implement SyncFormatsProvider for definitions that are already loaded. Treat an undefined result as a synchronous cache miss and use the asynchronous provider path when loading is acceptable.
Characteristics:
- Loads formats from KindOfQuantity definitions in schemas
- Filters formats by unit system preference group. See Unit Systems and UnitSystemKey for how each key maps to EC UnitSystems
- Throws an error for invalid EC full names
- Read-only format provider
Format selection
When a unit system is provided, SchemaFormatsProvider checks a KindOfQuantity in this order:
- Presentation formats, using the unit-system preference order and the order declared by the KindOfQuantity
- The persistence unit, represented as a basic decimal format when its unit system matches
- The default presentation format
Without a unit system, it uses the default presentation format. getFormatSync follows the same order but reads only schema metadata already loaded in the SchemaContext. If required metadata is not cached, it returns undefined instead of loading a schema; use getFormat when loading is acceptable.
Example: Simple Formatting
Formatting with SchemaFormatsProvider
Example: Parsing
Parsing with SchemaFormatsProvider
Example: Unit System Override
When retrieving a format from a schema, you might want to ensure the format matches your current unit system. You can pass the unit system on initialization or change it afterward:
Formatting with Unit System Override
Example: Retrieving KindOfQuantity and Persistence Unit
When you only have a KindOfQuantity name, you can use a SchemaContext to find the schema item and access its persistence unit:
Using SchemaContext to get KindOfQuantity and persistence unit
MutableFormatsProvider
MutableFormatsProvider extends the read-only FormatsProvider by allowing formats to be added or removed at runtime.
Characteristics:
- Supports dynamic format management
- Can add custom formats not in schemas
- Can override schema-defined formats
- Fires
onFormatsChangedevent when formats are modified
Example: Implementation
Example MutableFormatsProvider implementation
Example: Adding Formats
Adding formats to MutableFormatsProvider
FormatSetFormatsProvider
FormatSetFormatsProvider manages formats within a FormatSet. This provider automatically updates the underlying format set when formats are added or removed, making it ideal for applications that need to persist format changes.
Key Features:
- String Reference Resolution: Automatically resolves string references to their target FormatDefinition. When a format references another via string (e.g.,
"DefaultToolsUnits.LENGTH": "CivilUnits.LENGTH"), the provider resolves and returns the actual FormatDefinition. - Chain Resolution: Supports chains of references with circular reference detection.
- Cascade Notifications: When adding or removing a format, the
onFormatsChangedevent includes not only the modified format but also all formats that reference it (directly or indirectly). - Fallback Provider: String references can resolve through an optional fallback provider if the target format isn't found in the format set.
FormatSetFormatsProvider also implements SyncFormatsProvider. getFormatSync resolves local entries and synchronous fallbacks without awaiting. It returns undefined when the format is missing or the fallback is asynchronous.
Both lookups forward the lookup context to the fallback provider to stop fallback cycles. The cycle check tracks providers, not format names: if a fallback calls back into the same FormatSetFormatsProvider with that context, the lookup returns undefined, even for a different format. A fallback that needs an independent lookup should call without the context.
Example: FormatSet with String References
Using FormatSetFormatsProvider with string references
AlternateUnitLabelsProvider
AlternateUnitLabelsProvider allows specifying alternate labels for units during parsing. This is useful for:
- Supporting common abbreviations (e.g., "ft" and "foot" for feet)
- Enabling easier keyboard input (e.g., "^" for degrees "°")
- Accommodating regional variations in unit labels
Registering Providers in iTwin Applications
This section covers how to register and configure providers in your iTwin application. Proper provider registration ensures consistent quantity formatting across your application.
Registering UnitsProvider
Manual Registration
You can manually register a SchemaUnitProvider when opening an iModel:
Manual SchemaUnitProvider registration
Automatic Registration on IModelConnection Open
The recommended approach is to automatically register the provider when any IModelConnection opens:
Automatic registration via IModelConnection.onOpen
If errors occur while configuring the units provider, they are caught within the QuantityFormatter.setUnitsProvider method, and the code reverts back to BasicUnitsProvider.
Registering FormatsProvider
Using SchemaFormatsProvider
Register a SchemaFormatsProvider to load formats from iModel schemas:
Registering SchemaFormatsProvider on IModelConnection open
Using FormatSetFormatsProvider
For applications that persist user format preferences:
Registering FormatSetFormatsProvider with IModelApp
Adding Alternate Unit Labels
Add alternate unit labels for easier input during parsing:
Adding alternate unit labels
Configuring Unit System
Set the active unit system for the QuantityFormatter:
Configuring unit system
See Also
- Units - Understanding unit definitions
- Formats - Format specifications
- Format Sets - Application-level format persistence
- Parsing and Formatting - Using providers with FormatterSpec and ParserSpec
Last Updated: 02 October, 2026