← Back to list

iTwin.js: Node.js Application Handling iModel Briefcases with Ease

In this blog, we will explore how to build a Node.js application that using iTwin.js to download and process a briefcase. This guide is…

Asad Bukhari · 2025-03-27 10:28 · 0 claps · 3.4 min read
#itwinjs #itwin-platform #digital-twin #digital-twin-technology #bentley-systems
Open on Medium ↗
Wiki topics: 🌐 · Web Development

iTwin.js: Node.js Application Handling iModel Briefcases with Ease

In this blog, we will explore how to build a Node.js application that using iTwin.js to download and process a briefcase. This guide is designed for developers looking to work with large-scale infrastructure data while maintaining synchronization across different users and systems.

iTwin.js Node Application

iTwin.js Node Application

Understanding Briefcases in iTwin.js

A Briefcase in iTwin.js represents a local copy of an iModel, allowing editing and synchronization with the iModel Hub.

For mode details about Digital Twin terms refer to my blog Understanding terms iTwin, iTwin Plaform, iModelHub, iModel, Briefcases, and Changesets

Step-by-Step Guide

Step 1: Setup a Sample Node.js Project

Set up a sample Node.js Project by using the steps listed in my blog Authorizing Node CLI using iTwin.js.

Step 2: Create iTwin and iModel

  1. Go to Bentley Developer Portal > Profile > My iTwins.
  2. Create a new iTwin Project, or use an already existing one.
  3. After creating the iTwin project, create an iModel.
  4. You can select an existing Bentley Sample iModel or create an Empty iModel. In this example, we will use the Stadium iModel template.

Create Stadium Sample iModel

Create Stadium Sample iModel

Once the iModel is created, use the Copy IDs option to copy the iTwin and iModel ID.

Step 3: Configure the .env File

Before running the application, create a .env file and define the necessary configurations:

LOG_LEVEL=Error
CLIENT_ID=[Set your client id]
ITWIN_ID=[Set your iTwin id]
IMODEL_ID=[Set your iModel id]
MY_SERVICE_TMP_DIR=./tmp

Step 4: Implement Logging (Optional)

Logging is an essential part of debugging and monitoring application performance. The following script initializes logging in the backend:

//BackendLogger.ts

import { Logger, LoggerLevelsConfig } from "@itwin/core-bentley";
import config from "./Logger.config.json";

export function initializeLogging(logLevel: string = "Error"): void {
  Logger.initializeToConsole();

  // Configure log levels by category
  if ("loggerConfig" in config) {
    config.loggerConfig.defaultLevel = logLevel;
    Logger.validateProps(config.loggerConfig);
    Logger.configureLevels(config.loggerConfig as LoggerLevelsConfig);
  }
}

Step 5: Download and Read Elements

Create/update the index.ts file using BriefcaseManager, IModelHost, and BriefcaseDb from @itwin/core-backend.

Every iTwin.js backend must call [IModelHost.startup](https://www.itwinjs.org/reference/core-backend/imodelhost/imodelhost/startupstatic/). [IModelHost](https://www.itwinjs.org/learning/backend/imodelhost/) initializes the necessary components to access iModels and serve iTwin.js service.

Using [BriefcaseManager.downloadBriefcase](https://www.itwinjs.org/reference/core-backend/imodels/briefcasemanager/downloadbriefcasestatic/), download a new briefcase from iModelHub for the supplied iModelId.

Once the briefcase is downloaded, use [BriefcaseDb.open](https://www.itwinjs.org/reference/core-backend/imodels/briefcasedb/openstatic/) to open it and list all the elements inside.

Here is the complete code snippet, reading .env file, intializing logger, authorizing, start iModelHost, downloading and listing the elements.

/**
 * @file index.ts
 * @description This file initializes the iModelHost, downloads a briefcase, processes its elements, and releases the briefcase.
 * It uses environment variables for configuration and performs authentication using NodeCliAuthorizationClient.
 */

import { BriefcaseDb, BriefcaseManager, IModelHost, KnownLocations } from "@itwin/core-backend";
import { Logger } from "@itwin/core-bentley";
import { RequestNewBriefcaseProps } from "@itwin/core-common";
import { BackendIModelsAccess } from "@itwin/imodels-access-backend";
import { NodeCliAuthorizationClient } from "@itwin/node-cli-authorization";
import * as dotenv from "dotenv";
import path from "path";
import { initializeLogging } from "./BackendLogger";

// Load environment variables from .env file
dotenv.config();

const clientId = process.env.CLIENT_ID || "";
const iTwinId = process.env.ITWIN_ID || "";
const iModelId = process.env.IMODEL_ID || "";
const LogLevel = process.env.LOG_LEVEL || "Error";

if (!clientId || !iTwinId || !iModelId) {
  throw new Error("Must specify a valid configuration with CLIENT_ID, ITWIN_ID, and IMODEL_ID");
}

const authClient = new NodeCliAuthorizationClient({ clientId, scope: "itwin-platform" });
let accessToken: string = "";

/**
 * Initializes the iModelHost with the specified cache directory and authorization client.
 * @async
 * @function startupIModelHost
 * @returns {Promise<void>}
 */
const startupIModelHost = async (): Promise<void> => {
  let cacheDir = process.env.MY_SERVICE_CACHE_DIR;
  if (!cacheDir) {
    const tempDir = process.env.MY_SERVICE_TMP_DIR || KnownLocations.tmpdir;
    cacheDir = path.join(tempDir, "iModelJs_cache");
  }

  await IModelHost.startup({ cacheDir, authorizationClient: authClient, hubAccess: new BackendIModelsAccess() });
};

/**
 * Downloads a briefcase, processes its elements, and releases the briefcase.
 * @async
 * @function downloadAndProcessBriefcase
 * @returns {Promise<void>}
 */
const downloadAndProcessBriefcase = async (): Promise<void> => {
  const requestNewBriefcaseProps: RequestNewBriefcaseProps = {
    iTwinId: iTwinId, 
    iModelId: iModelId,
  };

  const localBriefcaseProps = await BriefcaseManager.downloadBriefcase(requestNewBriefcaseProps);
  const briefcaseDb = await BriefcaseDb.open({ fileName: localBriefcaseProps.fileName, readonly: true });

  Logger.logInfo("Backend.BriefcaseManager", `Opened Briefcase Id: ${briefcaseDb.briefcaseId}`);

  const idSet = briefcaseDb.queryEntityIds({ from: "BisCore.Element" });

  idSet.forEach(id => {
    const element = briefcaseDb.elements.getElement(id);
    Logger.logInfo("Backend.BriefcaseManager", `Element Id: ${element.id}, ClassName: ${element.className}`);
  });

  briefcaseDb.close();
  await BriefcaseManager.releaseBriefcase(accessToken, localBriefcaseProps);
};

/**
 * Main function to execute the process of signing in, initializing logging, starting up iModelHost,
 * downloading and processing the briefcase, and signing out.
 * @async
 * @function main
 * @returns {Promise<void>}
 */
(async (): Promise<void> => {
  try {
    console.log("Starting browser based sign in...");

    await authClient.signIn();  // Sign in to iTwin.js
    accessToken = await authClient.getAccessToken();

    initializeLogging(LogLevel);
    await startupIModelHost();
    await downloadAndProcessBriefcase();

    await authClient.signOut(); // Sign out of iTwin.js
  } catch (error) {
    console.error("Error during execution:", error);
  }
})();

Conclusion

In this blog, we walked through the setup and execution of a Node.js application that interacts with iTwin.js to download and process a briefcase. Find the complete source code on GitHub: iTwinjsStarterKit

This serves as a foundational guide for developers looking to build scalable infrastructure applications using iTwin.js.


메타데이터
post_id
3e07bb65344e
slug
itwin-js-node-js-application-handling-imodel-briefcases-with-ease-3e07bb65344e
url
https://medium.com/@asad_bukhari/itwin-js-node-js-application-handling-imodel-briefcases-with-ease-3e07bb65344e
canonical_url
https://medium.com/@asad_bukhari/itwin-js-node-js-application-handling-imodel-briefcases-with-ease-3e07bb65344e
author_url
https://medium.com/@asad_bukhari
status
ok
fetched_at
2026-07-13 06:23:13