Snap SDK
HERE Core Snap SDK works with the Windows operating system only.
The layout capabilities of HERE Core platforms allow end users and developers to compose collections of multiple web apps in a single window. This primary capability means that users can run apps side by side, even if those apps are produced by different teams or different vendors, without the need to toggle between windows to get tasks done.
With Snap SDK, HERE extends its layout capabilities to snapping windows together, allowing them to be grouped to behave like a single window. One of the most powerful aspects of Snap SDK is that this ability to create window groups is not restricted to HERE Core windows. With Snap SDK it is possible to group almost any window on the desktop.
Key features:
- Group almost any desktop window, not just HERE Core windows
- Move, minimize, restore, and switch between grouped windows as a single unit
- Resize windows when grouping so they align with targeted windows
- Works with desktop applications (Excel, custom .NET apps, etc.)
- Compatible with Windows® Snap layout in Windows® 10 and 11
- Integrates with the Windows® Taskbar and window switching through alt/win-tab hotkeys.
Developers choose which applications’ windows should participate in snapping. They can either programmatically attach windows or let the user do it themselves, in which case the Snap SDK’s grouping overlays guide them to attach windows. Grouped windows can be moved, minimized, restored, and switched to as a single unit. All user actions with grouping or ungrouping are also available as events, allowing developers to save and restore state as needed.
The technology powering Snap SDK under the hood is written in the Rust programming language to maximize security and performance. However, this is completely abstracted from developers through our TypeScript package available in the npm registry.
Download the Snap SDK client
The Snap SDK client library is an npm package that provides TypeScript Snap SDK APIs. As a developer, you must have Node.js installed in order to use it. To download and install the Snap SDK package, issue the following command in your HERE Core project directory:
npm install @openfin/snap-sdk@SNAP_SDK_VERSION
You can also use yarn to install the client.
yarn add @openfin/snap-sdk@SNAP_SDK_VERSION
You need to specify @SNAP_SDK_VERSION if you want a particular version. If you don't, the current version is installed.
Include the Snap SDK service
Snap SDK is a two-part system consisting of the client, described above, and the service, which is a standalone executable file (OpenFinSnap.exe) that operates on the local computer.
A compatible version of the Snap SDK service is automatically fetched by the client library (1.1+), or it can be specified and downloaded by creating an appAssets entry in the platform manifest.
📘 Note
Specifying
SNAP_SDK_VERSIONis required only if you do not want to use the default version, or if you deploy to environments where access to the HERE CDN is not available.
This entry instructs your platform to download a specific version of the Snap SDK service if it does not already exist on your computer:
"appAssets": [
{
"src": "https://cdn.openfin.co/release/snap/SNAP_SDK_VERSION/snap.zip",
"alias": "openfin-snap",
"version": "SNAP_SDK_VERSION",
"target": "OpenFinSnap.exe",
"mandatory": true
}
]
The Snap SDK client libraries are flexible enough to allow you to deploy the Snap SDK service through any other mechanism that works for your users. For example, you may wish to deploy the executable to your desktops using Microsoft SCCM rather than having it dynamically downloaded by HERE Core. In this case, when using the client to start the server, you can specify the executable’s path on the local system.
Add Snap SDK code to your HERE Core app or platform
Import the client library in your platform provider file:
const snapServer: Snap.SnapServer | undefined;
...
// Set the Here Snap SDK server ID to the platform UUID.
snapServer = new Snap.SnapServer(fin.me.identity.uuid);
Start Snap SDK Server
Start the SnapServer object. The start method takes an optional ServerOptions object.
// Download and start Here Snap SDK.
await snapServer.start({
theme: "snap-light1",
taskbarIcon: "http://here.io/favicon.ico",
taskbarIconGroup: "openfin_apps_group.my-group",
hideTaskbarEntry: true,
keyToStick: true,
});
This method starts the Snap SDK service as a hidden application.
OpenFinSnap.exe appears in the Windows Task Manager.
Register HERE Core platform windows with Snap SDK
Snap SDK doesn't manage every window on the system by default. It manages only those windows that are registered with Snap SDK.
To register your HERE Core platform windows with Snap SDK, there are two ways to do it:
Method one: Start a new window and explicitly register it with Snap SDK by using the registerWindow function:
// Get a HERE Core window to register with Snap SDK.
// In this example, we use the platform provider window.
const win = fin.Window.getCurrentSync();
const nativeId = await win.getNativeId();
// Register the platform window with Here Snap SDK.
await snapServer.registerWindow(fin.me.identity.uuid, nativeId);
Method two: Automatically register any newly created platform windows with Snap SDK by using the enableAutoWindowRegistration function. This automatically performs the tasks in Method one for each new platform window.
await snapServer.enableAutoWindowRegistration();
Listen to window events for snapped windows
Snap SDK injects code into each window to inspect and make available several WIN32 window messages as events in your platform. These events are made available from HERE Core windows as well as from native application windows.
The events are:
| Event Name | Handler | Description |
|---|---|---|
client-registered / client-unregistered | ClientRegisteredEvent / ClientUnRegisteredEvent | Inform when a new window has been registered or unregistered with Snap SDK. |
clients-attached / client-detached | ClientsAttachedEvent / ClientDetachedEvent | Inform when windows have been snapped together or unsnapped from the window group. |
client-activated / client-deactivated | ClientActivatedEvent / ClientDeactivatedEvent | Inform when a window has been activated or deactivated. |
move-size-completed | MoveSizeCompletedEvent | Inform when a window and its attached windows were moved or were resized. |
groups-changed | GroupsChangedEvent | Inform when any window groups have been modified. |
An example of a client-activated event handler:
snapServer.addEventListener(
"client-activated",
(event: Snap.ClientActivatedEvent) => {
console.log(`Client Activated: ${JSON.stringify(event)}`);
},
);
Attach and detach windows from window groups with Snap SDK
To attach a window to a window group using the UI, you click and drag a window to a window group. To detach a window from a window group, you shift-click and drag a window away from a window group. Overlays guide users to the desired side.

To programmatically attach a window to a window group, use the attachWindows function:
// Attach myWindowId to the specified window group.
await snapServer.attachWindows(fin.me.identity.uuid, myWindowId, "right", 0);
To programmatically detach a window from a window group, use the detachFromGroup function:
await snapServer.detachFromGroup(myWindowId);
Snapshots with Snap SDK
HERE Core snapshots can be stored in the platform manifest. Snap SDK adds decorations (Snap SDK-specific JSON properties) to the platform manifest to describe Snap SDK managed windows and their relationship to a window group. This adds extra steps to creating and applying snapshots.
To create a Snap SDK snapshot:
-
Call getSnapshot.
-
Call decorateSnapshot to add the Snap SDK decorations to the snapshot.
To apply a snapshot:
-
Call prepareToApplySnapshot to inform the platform that it will soon apply a Snap SDK decorated snapshot.
-
Apply the snapshot in the usual way.
-
Apply the Snap SDK decorations to the snapshot.
While it is possible to save snapshot details containing snapped windows, applying a snapshot does not automatically launch the windows participating in that snapshot. It is the responsibility of the platform developer to launch the desktop applications within a snapshot.
// Set up HERE Core snapshot integration
fin.Platform.init({
overrideCallback: async (PlatformProvider, ...overrideArgs) => {
try {
class WithSnap extends PlatformProvider {
async getSnapshot(
...args: [undefined, OpenFin.ClientIdentity]
): Promise<OpenFin.Snapshot> {
// Create the platform snapshot.
const snapshot = await super.getSnapshot(...args);
// Add the Snap SDK properties to the platform snapshot.
const snapSnapshot = await snapServer.decorateSnapshot(snapshot);
return snapSnapshot;
}
async applySnapshot(
...args: [OpenFin.ApplySnapshotPayload, OpenFin.ClientIdentity]
): Promise<void> {
// Prepare Snap SDK to return a snapshot.
await snapServer.prepareToApplySnapshot();
// Apply the main snapshot.
await super.applySnapshot(...args);
// Apply the Snap SDK decorations to the snapshot.
await snapServer.applySnapshot(args[0].snapshot);
}
}
return new WithSnap(...overrideArgs);
} catch (error) {
return new PlatformProvider();
}
},
});
Defer layout updates
You might encounter a situation where you have more than a few snapped windows and you want to resize them all programmatically. Typically, doing so results in delayed performance and a visual cascade effect. To avoid this performance hit, starting in Snap version 1.3.3, you can tell Snap to defer its updates to the layout until you are finished making your changes. Use the enterDeferredLayout() and exitDeferredLayout() methods before and after you update several snapped windows.
Desktop application windows in Snap SDK
Desktop application support enables classic Windows applications (such as Excel) and custom .NET apps to snap to a window group alongside HERE Core windows.
There are two ways to integrate a desktop application with Snap SDK:
- Snap SDK-launched applications: Snap SDK launches the application process and automatically identifies and registers its main window.
- Independently launched applications: The application is launched outside of Snap SDK (for example, through click-once deployment or shell execution), and Snap SDK captures its window after the fact.
Launching desktop applications with Snap SDK
To have Snap SDK launch and manage a desktop application, call launch, passing in a LaunchOptions object.
The LaunchOptions object contains these properties: The path to the executable file, a unique string clientId, a string array of command line args, and an optional strategy to identify the native application's main window.
Here is a simple example of a launch function to launch Microsoft Excel and open my-spreadsheet.xlsx:
// Launch Windows 10 Excel managed by Snap SDK.
const launchResult = await snapServer?.launch({
'C:\\Program Files\\excel.exe', // Path to Excel.
'excel-#1', // Unique client ID string.
['c:\\my-docs\my-spreadsheet.xlsx'] // Array of string arguments to be passed.
});
In addition to launching with an executable, you can also launch with an associated file (for example, a .jar file). To do so, replace the executable's path shown with the absolute path of the associated file.
Window identification strategies
Snap SDK needs basic information about an app's windows to enable Snap functionality. This applies to both those created on launch and those created by user action. Because no general standard exists for obtaining this information, Snap SDK supports multiple strategies for launching apps.
The optional strategy property of LaunchOptions accepts the following strategy types:
-
The
waitForWindowOfNamestrategy waits until the process opens a window with a title that matches a regular expression rule. If the strategy doesn't find a matching window within the specified timeout period, the process fails. -
The
waitForWindowOfClassstrategy waits for a window whose underlying WIN32 Window Class matches a regular expression rule. If the strategy doesn't find a matching window within the specified timeout period, the process fails. -
The
delaystrategy waits for a specified time period, then captures the first window available. -
The
combinedstrategy combines thewaitForWindowOfName,waitForWindowOfClass, anddelaystrategies. -
The
independentstrategy, discussed in the Integrating independently launched applications section.
If no strategy is specified, the delay strategy is used by default.
This is an example of using the waitForWindowOfName strategy to identify the applicable window of a custom process:
const launchResult = await snapServer?.launch({
'my_custom_process.exe', // Path to custom process.
'custom-process-#1', // Unique client ID string.
[], // Empty array to indicate a strategy will be used.
{
type: 'waitForWindowOfName', // Strategy to use to identify the window.
timeoutMs: 15000, // Timeout in milliseconds.
matchRegex: '^My Process Title', // Regular expression to match title of window.
}
});
Integrating independently launched applications
Some desktop applications are launched outside of the Snap SDK process — for example, through click-once deployment, shell execution, or other external mechanisms. Previously, these applications could not participate in snapping because Snap SDK had to launch them directly.
The independent strategy removes that requirement. It captures top-level windows belonging to external applications that are already running or that are launched independently of Snap SDK. This enables integration with applications outside the HERE Core ecosystem without changing how those applications are deployed or started.
To use the independent strategy, call launch with the strategy type set to independent:
const launchResult = await snapServer?.launch({
'my_clickonce_app.exe', // Path to the externally launched application.
'clickonce-app-#1', // Unique client ID string.
[], // Empty array (no launch arguments needed).
{
type: 'independent', // Strategy for independently launched applications.
timeoutMs: 15000, // Timeout in milliseconds for window search.
matchNameRegex: '^My App Title', // Optional: regex to match the window caption.
}
});
Unlike the other strategies, the independent strategy does not require Snap SDK to start the application process. Its behavior depends on the alwaysLaunchNewInstance strategy:
-
If
true, the strategy always launches a new instance, regardless of whether one is already running. -
If
false, the strategy only searches for an existing running instance. If apathis provided and no running instance is found, it can optionally launch a new one.
The IndependentStrategy object accepts the following properties:
| Property | Required | Description |
|---|---|---|
type | Yes | Must be set to "independent". |
timeoutMs | Yes | The timeout period in milliseconds after which the window search is abandoned. |
matchNameRegex | No | A regular expression string to match the window caption. If not provided, any window caption matches. |
matchClassRegex | No | A regular expression string to match the WIN32 Window Class. If not provided, any window class matches. |
alwaysLaunchNewInstance | No | If true, always launches a new application instance even if one or more instances already exist. Defaults to false. |
resizingBehavior | No | Controls the resizing behavior of the window when snapped. |
If both matchNameRegex and matchClassRegex are provided, windows must match both the caption and class regular expressions.
If neither matchNameRegex or matchClassRegex are provided, then no window is matched.