Skip to content

Releases: iTwin/itwinjs-core

v5.8.0

02 Apr 19:56

Choose a tag to compare

5.8.0 Change Notes

@itwin/core-backend

WithQueryReader API

A new withQueryReader method has been added to both ECDb and IModelDb, providing true row-by-row behavior for ECSQL queries with synchronous execution. This API introduces a new ECSqlSyncReader through the ECSqlRowExecutor and supports configuration via SynchronousQueryOptions.

Key Features:

  • True row-by-row streaming: Unlike the existing async reader APIs, withQueryReader provides synchronous row-by-row access to query results
  • Consistent API across databases: The same interface is available on both ECDb and IModelDb instances
  • Configurable behavior: Support for various query options through SynchronousQueryOptions

Usage Examples:

// ECDb usage
db.withQueryReader("SELECT ECInstanceId, UserLabel FROM bis.Element LIMIT 100", (reader) => {
  while (reader.step()) {
    const row = reader.current;
    console.log(`ID: ${row.id}, Label: ${row.userLabel}`);
  }
});

// IModelDb usage with options
iModelDb.withQueryReader(
  "SELECT ECInstanceId, CodeValue FROM bis.Element",
  (reader) => {
    while (reader.step()) {
      const row = reader.current;
      processElement(row);
    }
  }
);

Migration from deprecated APIs:

This API serves as the recommended replacement for synchronous query scenarios previously handled by the deprecated ECSqlStatement for read-only operations:

// Before - using deprecated ECSqlStatement
db.withPreparedStatement(query, (stmt) => {
  while (stmt.step() === DbResult.BE_SQLITE_ROW) {
    const row = stmt.getRow();
    processRow(row);
  }
});

// Now - using withQueryReader
db.withQueryReader(query, (reader) => {
  while (reader.step()) {
    const row = reader.current;
    processRow(row);
  }
});

Dedicated SettingsDb for workspace settings

A new SettingsDb type has been added to the workspace system, providing a dedicated database for storing JSON settings as key-value pairs, separate from general-purpose WorkspaceDb resource storage.

Why SettingsDb?

Previously, settings and binary resources (fonts, textures, templates) were stored together in WorkspaceDb containers. This coupling created issues:

  • Lookup: Finding which containers hold settings required opening each one
  • Granularity: Settings updates required republishing entire containers with large binary resources
  • Separation of concerns: Settings (JSON key-value) and resources (binary blobs) have different access patterns

New APIs

  • SettingsDb: Read-only interface with getSetting() and getSettings() for accessing settings stored in a dedicated database
  • EditableSettingsDb: Write interface with updateSetting(), removeSetting(), and updateSettings() for modifying settings within a SettingsDb
  • SettingsEditor: Write interface for creating and managing SettingsDb containers
  • Workspace.getSettingsDb: Method to open a SettingsDb from a previously-loaded container by its containerId and desired priority

Usage examples

Creating a local SettingsDb

[[include:SettingsDb.createLocal]]

See SettingsDb for full documentation.

Container type convention

SettingsDb containers use containerType: "settings" in their cloud metadata, enabling them to be discovered independently of any iModel.

Container separation and lock isolation

Settings containers are deliberately separate from workspace containers. Both extend the new CloudSqliteContainer base interface, but EditableSettingsCloudContainer does not extend WorkspaceContainer. This means:

  • Independent write locks: Editing settings does not lock out workspace resource editors, and vice versa.
  • Clean API surface: Settings containers do not inherit workspace-db read/write methods (getWorkspaceDb, addWorkspaceDb, etc.), exposing only settings-specific operations.
  • Type safety: Code that receives an EditableSettingsCloudContainer cannot accidentally add or retrieve WorkspaceDbs from it.

Display

Fixes

  • Fixed reality data geometry not being reprojected correctly when the reality data is in a different CRS than the iModel.

Electron 41 support

In addition to already supported Electron versions, iTwin.js now supports Electron 41.

Quantity Formatting

Reverted default metric engineering length in QuantityFormatter

The default metric engineering length format introduced in iTwin.js 5.7.0 has been reverted. Applications using QuantityFormatter with QuantityType.LengthEngineering will once again display metric engineering lengths in meters with 4 decimal places (e.g. 1000 m) rather than millimeters.

v5.7.3

24 Mar 15:38

Choose a tag to compare

Release notes

Changes

  • Security Fix: Remove unnecessary fast-xml-parser override (backport #9095) [release/5.7.x] (#9096)
  • Revert default engineering length metric formatting to meters (backport #9120) [release/5.7.x] (#9121)

Full changelog: 5.7.2...5.7.3

v5.7.2

12 Mar 14:52

Choose a tag to compare

Release notes

Changes

  • 5.6.3 Changelogs
  • Bugfix/default civilunits length koq (backport #9071) [release/5.7.x] (#9072)
  • Fix reality data not being reprojected correctly when its CRS is different than iModel (backport #9059) [release/5.7.x] (#9075)
  • Security: fix high-severity CVE-2026-30951 (GHSA-6457-6jrx-69cr) in sequelize (backport #9080) [release/5.7.x] (#9081)

Full changelog: 5.7.1...5.7.2

v5.7.1

09 Mar 15:22

Choose a tag to compare

Release notes

Changes

  • sparse wmts datasource fixes (backport #9024) [release/5.7.x] (#9053)
  • @bentley/imodeljs-native 5.7.11
  • @bentley/imodeljs-native 5.7.12
  • @bentley/imodeljs-native 5.7.13

Full changelog: 5.7.0...5.7.1

v5.7.0

03 Mar 19:03

Choose a tag to compare


deltaDoc: true
version: '5.7.0'

5.7.0 Change Notes

Semantic rebase (beta)

A new useSemanticRebase option has been added to IModelHostConfiguration. When enabled, pullChanges can intelligently merge local and incoming changes that involve schema modifications — a scenario where traditional binary changeset merging produces incorrect results.

Instead of requiring an exclusive lock for schema changes, semantic rebase captures local changes as high-level representations (schema XML and instance patches), applies incoming changesets, then re-applies local changes against the updated schema. This allows schema changes to use shared locks, reducing lock contention.

Limitations:

  • Incompatible schema changes on both sides may cause the rebase to be rejected. To minimize risk, push schema changes promptly and separately from data changes.
  • Cannot be used alongside Schema Sync.
  • Profile upgrades still require exclusive locks.

Electron 40 support

In addition to already supported Electron versions, iTwin.js now supports Electron 40.

Note: with Electron 40, Chromium no longer uses SwiftShader as an automatic fallback for WebGL. This may cause issues when Electron is run in an environment without a supported GPU. For more information: Using Chromium with SwiftShader.

Display

Batch category display changes

Viewport.changeCategoryDisplay now accepts an optional batchNotify parameter. When set to true, a single notification event is raised after all categories have been added or removed, rather than one event per category. This significantly improves performance when changing the visibility of a large number of categories at once.

// Before: each category triggers a separate event, causing poor performance for large sets
viewport.changeCategoryDisplay(categoryIds, true);

// After: a single batch event is raised after all categories are updated
viewport.changeCategoryDisplay(categoryIds, true, undefined, true);

The default behavior (batchNotify = false) is unchanged, preserving backward compatibility.

Additionally, ObservableSet now provides addAll and deleteAll methods for batch mutations, along with corresponding onBatchAdded and onBatchDeleted events. CategorySelectorState exposes these via addCategoriesBatched and dropCategoriesBatched.

Quantity Formatting

Updated default engineering lengths in QuantityFormatter

For applications and tools using QuantityFormatter and QuantityType APIs, the default engineering length formatting, retrieved via QuantityType.LengthEngineering has been updated. Metric engineering lengths now use millimeters with 3 decimal places; imperial engineering lengths use feet with 2 decimal places.

Fix `Quantity.convertTo()` return type to reflect actual behavior

The Quantity.convertTo() method has always returned a valid Quantity object since its initial implementation. However, its TypeScript signature incorrectly indicated it could return undefined with the type Quantity | undefined. This has been corrected to return Quantity.

Quantity code that was defensively checking for undefined or using non-null assertions (!) can now be simplified. TypeScript will no longer warn about possible undefined values when calling this method.

Presentation

Reducing the number of properties that are loaded with content

The Descriptor class, which describes the content to be loaded, now has a fieldsSelector property that allows specifying which fields should be included or excluded in the content. This is useful for cases when only a subset of fields is needed, which can reduce the amount of data that needs to be loaded and processed.

Similarly, the backend's PresentationManager.getElementProperties method now accepts an optional fieldsSelector parameter, which allows clients to specify which properties should be included or excluded in the response.

Reducing the number of fields that are loaded with content can improve performance, especially for large datasets, by minimizing the amount of data that needs to be transferred and processed.

API Deprecations

`logException()`

Deprecated Replacement
logException() Use logError() instead

The @itwin/core-bentley logging method for logging exceptions logException() was redundant with logError() and it was often unclear as to when either should be used. logException() ended up just calling logError() but allowed for passing in error objects instead of a message.

A new logError() overload is now provided to maintain this functionality, logging errors passed in the same way as logException() but also providing the option to provide LoggingMetaData in addition to the error, which logException() did not support.

logException() will not be removed until the alloted deprecation window has passed, as per our breaking changes policy.

v5.6.2

26 Feb 22:57

Choose a tag to compare

Release notes

Changes

Full changelog: 5.6.1...5.6.2

v5.6.1

13 Feb 17:52

Choose a tag to compare

Release notes

Changes

  • exception for CVE-2026-25639 (backport #8971) [release/5.6.x] (#8972)
  • @bentley/imodeljs-native 5.6.13
  • ElementGeometry.appendTextBlock. Fix incorrect 'if' comparison against color (backport #8983) [release/5.6.x] (#8984)
  • @bentley/imodeljs-native 5.6.14
  • Add integrityCheck() function (backport #8958) [release/5.6.x] (#8986)

Full changelog: 5.6.0...5.6.1

v5.6.0

05 Feb 16:51

Choose a tag to compare


deltaDoc: true
version: '5.6.0'

5.6.0 Change Notes

Quantity Formatting

Ratio Format Enhancements

Ratio formats now support automatic scale factor conversion when using 2-unit composite formats. This enables proper display of architectural scales (e.g., 1/4"=1') and metric scales (e.g., 1:100) with automatic unit conversion.

How it works:

  • When a Ratio format has exactly 2 units in its composite.units array, the system automatically computes scale factor conversion
  • The first unit represents the numerator, the second represents the denominator
  • Both units must have matching phenomena (e.g., both LENGTH)
  • Scale factor is computed dynamically from the denominator→numerator conversion
  • Supports both decimal and fractional display modes

For detailed examples and documentation, see the Quantity Formatting documentation.

@itwin/presentation-common

Additions

  • Added parentArrayField and parentStructField attributes to PropertiesField class to allow easier navigation to parent fields when traversing content. The new properties, together with parent property, are mutually exclusive, i.e., only one of them can be defined at a time (a field can't be a struct member and an array item field at the same time).
  • Added getFieldByName method to ArrayPropertiesField and StructPropertiesField.
    • For array field, the method returns items field if its name matches the given name.
    • For struct field, the method returns the member field with the given name, if any.

Fixes

  • Fixed content traverser (result of createContentTraverser call) not passing parent struct / array field names as parentFieldName to IContentVisitor methods.

@itwin/core-backend

Database Optimization APIs

Three new database optimization APIs have been added to maintain optimal query performance and iModel file size.

vacuum()

Reclaims unused space and defragments the database file.

// After large deletions
briefcaseDb.vacuum();

analyze()

Updates SQLite query optimizer statistics.

// After large data imports or schema changes
briefcaseDb.analyze();

optimize()

Performs both vacuum() and analyze() operations in sequence. This is the recommended way to optimize an iModel.

For convenience, optimization can be performed automatically when closing an iModel by using the optimize property of the CloseIModelArgs:

// Automatically optimize when closing
briefcaseDb.close({ optimize: true });

Alternatively, call optimize() explicitly for more control over when optimization is needed:

// Optimize before closing
briefcaseDb.performCheckpoint(); // Changes might still be in the WAL file
briefcaseDb.optimize();
briefcaseDb.saveChanges();

// Later close without re-optimizing
briefcaseDb.close();

TextAnnotation render priorities

TextAnnotation elements now support custom render priorities for better control over z-ordering in 2D views. The new renderPriority option in appendTextAnnotationGeometry allows you to specify different priorities for annotation labels versus other annotation geometry (frame, leaders, etc.).

import { appendTextAnnotationGeometry } from "@itwin/core-backend";

// Set different priorities for text labels and annotation geometry
appendTextAnnotationGeometry({
  annotationProps,
  layout,
  textStyleResolver,
  scaleFactor,
  builder,
  categoryId,
  renderPriority: {
    annotationLabels: 100, // Priority for text block and fill
    annotation: 50, // Priority for frame, leaders, and other geometry
  },
});

The render priority values are added to SubCategoryAppearance.priority to determine the final display priority. This allows text annotations to render correctly relative to other 2D graphics. Note that render priorities have no effect in 3D views.

Display

BENTLEY_materials_planar_fill

Support has been added for the proposed BENTLEY_materials_planar_fill glTF extension.

This allows iTwin.js to process and apply the above extension when loading glTF files. This means mesh primitives will be able to have planar fill display properties specified and respected in iTwin.js when loaded via glTF. The extension supports controlling whether meshes are filled in wireframe mode, whether they fill with the background color, and whether they render behind other coplanar geometry belonging to the same logical object.

When this extension is present on a material, iTwin.js will apply the appropriate fill flags to control the rendering appearance of the associated mesh geometry.

Here is an example of wireframeFill being applied to a test dataset:

A rendering pointing to three colored quads with varying wireframeFill properties as specified via BENTLEY_materials_planar_fill

Here is an example of backgroundFill being applied to a test dataset:

A rendering pointing to one colored quad indicating its backgroundFill property is respected as specified via BENTLEY_materials_planar_fill

Here is an example of behind being applied to a test dataset:

A rendering pointing to an overlapping pair of colored coplanar quads indicating the behind property is respected as specified via BENTLEY_materials_planar_fill

EXT_textureInfo_constant_lod

Support was added for the proposed EXT_textureInfo_constant_lod glTF extension which supports constant level-of-detail texture mapping mode for glTF models. The mode is already supported for iModels, see the documentation from when it was introduced for more information.

iTwin.js supports EXT_textureInfo_constant_lod on the baseColorTexture property in glTF model materials, with fallback to emissiveTexture if baseColorTexture is not present. When the extension is present on normalTexture, it is only applied when baseColorTexture (or emissiveTexture) also has the extension, and the constant LOD properties from the base texture are used for both to keep texture mapping in sync.

The extension is not supported for occlusionTexture and metallicRoughnessTexture.

v5.5.2

22 Jan 16:58

Choose a tag to compare

Release notes

Changes

  • Fixed the issue of getAllBaseClasses() function not returning all the base classes (backport #8912) [release/5.5.x] (#8918)

Full changelog: 5.5.1...5.5.2

v5.5.1

14 Jan 18:28

Choose a tag to compare

Release notes

Changes

  • Fix past release toc headers (#8891)
  • fix iModelDb documentation include examples (backport #8894) [release/5.5.x] (#8895)
  • Add loaders.gl/core back as a dependency of frontend (backport #8900) [release/5.5.x] (#8902)

Full changelog: 5.5.0...5.5.1