> Part of the walkerOS documentation. Project overview and full index: <https://www.walkeros.io/llms.txt>

# Migration guide: from @elbwalker to @walkerOS

This guide helps you migrate from the old elbwalker packages to the new walkerOS packages.

## Quick reference[​](#quick-reference "Direct link to Quick reference")

### Core package changes[​](#core-package-changes "Direct link to Core package changes")

* `@elbwalker/walker.js` → `@walkeros/collector` + `@walkeros/web-source-browser`
* `@elbwalker/types` + `@elbwalker/utils` → `@walkeros/core`
* `@elbwalker/destination-web-*` → `@walkeros/web-destination-*`
* `@elbwalker/destination-node-*` → `@walkeros/server-destination-*`

## Step-by-step migration[​](#step-by-step-migration "Direct link to Step-by-step migration")

### 1. Update dependencies[​](#1-update-dependencies "Direct link to 1. Update dependencies")

**Before:**

```
{
  "dependencies": {
    "@elbwalker/walker.js": "^2.0.0",
    "@elbwalker/destination-web-google-ga4": "^2.0.0"
  }
}
```

**After:**

```
{
  "dependencies": {
    "@walkeros/collector": "^0.0.7",
    "@walkeros/web-source-browser": "^0.0.7",
    "@walkeros/web-destination-gtag": "^0.0.7"
  }
}
```

### 2. Update imports[​](#2-update-imports "Direct link to 2. Update imports")

**Before:**

```
import { Walkerjs } from '@elbwalker/walker.js';
import { destinationGoogleGA4 } from '@elbwalker/destination-web-google-ga4';
import type { WalkerOS } from '@elbwalker/types';
```

**After:**

```
import { startFlow } from '@walkeros/collector';
import { sourceBrowser } from '@walkeros/web-source-browser';
import { destinationGtag } from '@walkeros/web-destination-gtag';
import type { WalkerOS } from '@walkeros/core';
```

### 3. Update function calls[​](#3-update-function-calls "Direct link to 3. Update function calls")

**Before:**

```
const walker = Walkerjs({
destinations: [destinationGoogleGA4],
});
```

**After:**

```
const { elb } = await startFlow({
sources: {
browser: {
code: sourceBrowser,
config: {
  settings: { scope: document.body },
},
},
},
destinations: {
gtag: {
code: destinationGtag,
config: {
  settings: {
    ga4: { measurementId: 'G-XXXXXXXXXX' },
  },
},
},
},
});
```

## Breaking changes[​](#breaking-changes "Direct link to Breaking changes")

### 1. Unified collector[​](#1-unified-collector "Direct link to 1. Unified collector")

* Single `@walkeros/collector` package works across all platforms
* Use `startFlow()` instead of `Walkerjs()` or `createSourceNode()`

### 2. Modular sources[​](#2-modular-sources "Direct link to 2. Modular sources")

* DOM tracking is now `@walkeros/web-source-browser`
* Import and initialize sources separately

### 3. Core package merger[​](#3-core-package-merger "Direct link to 3. Core package merger")

* All types and utilities now come from `@walkeros/core`
* Update all import statements accordingly

### 4. Google destinations unified[​](#4-google-destinations-unified "Direct link to 4. Google destinations unified")

* GA4, Google Ads, and GTM are now unified in `@walkeros/web-destination-gtag`
* Configure all Google services through a single destination

## Destination configuration patterns[​](#destination-configuration-patterns "Direct link to Destination configuration patterns")

### Unified configuration approach[​](#unified-configuration-approach "Direct link to Unified configuration approach")

Configure all sources and destinations in a single `startFlow` call:

```
const { elb } = await startFlow({
sources: {
browser: {
code: sourceBrowser,
config: {
  settings: { scope: document.body, session: true },
},
},
},
destinations: {
gtag: {
code: destinationGtag,
config: {
  settings: {
    ga4: { measurementId: 'G-XXXXXXXXXX' },
  },
},
},
},
});
```

**Benefits:**

* Single configuration describing entire tracking setup
* Full type safety with proper config linking
* No manual destination registration needed
* Clean separation between code and configuration

## Migration checklist[​](#migration-checklist "Direct link to Migration checklist")

### Package dependencies[​](#package-dependencies "Direct link to Package dependencies")

* \[ ] Remove old `@elbwalker/*` packages
* \[ ] Add `@walkeros/collector`
* \[ ] Add required sources and destinations
* \[ ] Add `@walkeros/core` for custom implementations

### Code updates[​](#code-updates "Direct link to Code updates")

* \[ ] Update all imports to new packages
* \[ ] Replace collector initialization with `startFlow()`
* \[ ] Update type imports to use `@walkeros/core`
* \[ ] Test functionality after migration

## Common issues[​](#common-issues "Direct link to Common issues")

**"Cannot find module @walkeros/web-collector"**<br /><!-- -->Solution: Use `@walkeros/collector` + `@walkeros/web-source-browser`

**"elb is not defined"**<br /><!-- -->Solution: `elb` is returned by `startFlow()` function

**TypeScript cannot find types**<br /><!-- -->Solution: Import types from `@walkeros/core`

## data-elbaction vs data-elbactions[​](#data-elbaction-vs-data-elbactions "Direct link to data-elbaction vs data-elbactions")

### Breaking change in @walkeros packages[​](#breaking-change-in-walkeros-packages "Direct link to Breaking change in @walkeros packages")

The behavior of `data-elbaction` has changed to improve performance and provide more precise entity targeting:

* **@elbwalker behavior**: `data-elbaction` applied to **all entities** in the DOM hierarchy
* **@walkeros behavior**: `data-elbaction` applies to **nearest entity only**

### Migration strategy[​](#migration-strategy "Direct link to Migration strategy")

#### Option 1: keep current behavior (recommended for migration)[​](#option-1-keep-current-behavior-recommended-for-migration "Direct link to Option 1: keep current behavior (recommended for migration)")

Replace `data-elbaction` with `data-elbactions` to maintain the same behavior:

```
<!-- Before (@elbwalker) -->
<div data-elb="parent">
  <div data-elb="child" data-elbaction="click:action">
    <!-- Triggered both parent and child entities -->
  </div>
</div>

<!-- After (@walkeros) - Same behavior -->
<div data-elb="parent">
  <div data-elb="child" data-elbactions="click:action">
    <!-- Triggers both parent and child entities -->
  </div>
</div>
```

#### Option 2: use new behavior (recommended for new projects)[​](#option-2-use-new-behavior-recommended-for-new-projects "Direct link to Option 2: use new behavior (recommended for new projects)")

Use `data-elbaction` for more precise, performance-optimized tracking:

```
<!-- @walkeros - New behavior -->
<div data-elb="parent">
  <div data-elb="child" data-elbaction="click:action">
    <!-- Only triggers child entity -->
  </div>
</div>
```

### When to use each[​](#when-to-use-each "Direct link to When to use each")

**Use `data-elbaction` (nearest entity) when:**

* You want precise tracking of only the specific entity
* Performance is critical (fewer events)
* Implementing new features

**Use `data-elbactions` (all entities) when:**

* Migrating from @elbwalker and need same behavior
* You need context from parent entities
* Analytics requires full DOM hierarchy

### Tagger API[​](#tagger-api "Direct link to Tagger API")

The tagger also provides both methods:

```
// Nearest entity only (data-elbaction)
tagger().action('click', 'select').get();

// All entities (data-elbactions)
tagger().actions('click', 'select').get();
```

## visible vs impression triggers[​](#visible-vs-impression-triggers "Direct link to visible vs impression triggers")

### Breaking change in @walkeros packages[​](#breaking-change-in-walkeros-packages-1 "Direct link to Breaking change in @walkeros packages")

The visibility trigger names have been updated to better reflect their behavior:

* **`visible` trigger**: Now fires **multiple times** when element re-enters viewport (was `visibles`)
* **`impression` trigger**: Fires **once only** when element first becomes visible (was `visible`)

### Migration strategy[​](#migration-strategy-1 "Direct link to Migration strategy")

#### Option 1: update trigger names (recommended)[​](#option-1-update-trigger-names-recommended "Direct link to Option 1: update trigger names (recommended)")

Update your HTML to use the new trigger names:

```
<!-- Before (@elbwalker and early @walkeros) -->
<div data-elbaction="visible:view">Single fire</div>
<div data-elbaction="visibles:track">Multiple fires</div>

<!-- After (@walkeros current) -->
<div data-elbaction="impression:view">Single fire</div>
<div data-elbaction="visible:track">Multiple fires</div>
```

#### Option 2: understand the behavior change[​](#option-2-understand-the-behavior-change "Direct link to Option 2: understand the behavior change")

If you keep using the old names, understand the behavior has changed:

* Old `visible` behavior (single-fire) → Now use `impression`
* Old `visibles` behavior (multiple-fire) → Now use `visible`

### When to use each[​](#when-to-use-each-1 "Direct link to When to use each")

**Use `impression` trigger when:**

* You want to track when content is first seen
* Measuring ad impressions or content views
* One-time engagement metrics

**Use `visible` trigger when:**

* You want to track repeated interactions
* Measuring scroll behavior or re-engagement
* Analytics requires multiple visibility events

### Tagger API[​](#tagger-api-1 "Direct link to Tagger API")

The tagger supports both trigger types:

```
// Single impression (fires once)
tagger().action('impression', 'view').get();

// Multiple visibility (fires each time visible)
tagger().action('visible', 'track').get();
```
