Skip to main content
Ask your AI

Migration guide: from @elbwalker to @walkerOS

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

Quick reference​

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​

1. Update dependencies​

Before:

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

After:

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

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​

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​

1. Unified collector​

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

2. Modular sources​

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

3. Core package merger​

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

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​

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 },
},
},
},
destinations: {
gtag: {
code: destinationGtag,
config: {
  settings: {
    ga4: { measurementId: 'G-XXXXXXXXXX' },
  },
},
},
},
});

Benefits:

  • One configuration describes the entire tracking setup
  • Full type safety, with configs linked to their packages
  • No manual destination registration
  • Code and configuration stay separate

Migration checklist​

Package dependencies​

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

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​

"Cannot find module @walkeros/web-collector"
Solution: Use @walkeros/collector + @walkeros/web-source-browser

"elb is not defined"
Solution: elb is returned by startFlow() function

TypeScript cannot find types
Solution: Import types from @walkeros/core

data-elbaction vs data-elbactions​

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​

Replace data-elbaction with data-elbactions to keep the same behavior for the click and submit triggers:

<!-- 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>
note

data-elbactions on its own fires only for the click and submit triggers. All other triggers, such as load, visible, impression, hover, scroll, wait, and pulse, start only from an element with data-elbaction, which applies to the nearest entity; a matching data-elbactions entry on that same element takes precedence and applies to all entities.

Use data-elbaction for more precise tracking that fires fewer events:

<!-- @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​

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; on its own, click and submit only) when:

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

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​

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​

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​

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​

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​

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();
💡 Need implementation support?
elbwalker offers hands-on support: setup review, measurement planning, destination mapping, and live troubleshooting. Book a 2-hour session (€399)