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…
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
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
- Go to Bentley Developer Portal > Profile > My iTwins.
- Create a new iTwin Project, or use an already existing one.
- After creating the iTwin project, create an iModel.
- 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
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