# What Is the EGO_WRAPPED Symbol in ego-lite and Why Is It Used in installEgoSdk?

> Discover the EGO_WRAPPED symbol in ego-lite. Learn why it prevents duplicate helper injection and ensures idempotent installation with installEgoSdk.

- Repository: [CitroLabs/ego-lite](https://github.com/citrolabs/ego-lite)
- Tags: deep-dive
- Published: 2026-08-02

---

**EGO_WRAPPED is a unique Symbol that marks the global `ego` object after the Ego-Lite SDK has been installed, preventing duplicate helper injection and enabling idempotent installation.**

The `EGO_WRAPPED` symbol sits at the heart of ego-lite's installation safety mechanism. In [`src/index.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/index.ts), the `installEgoSdk()` function uses this symbol to detect whether the SDK has already been initialized on `globalThis.ego`. This pattern ensures that multiple calls to the installer produce no side effects—a critical guarantee for runtime stability in browser automation environments.

## How EGO_WRAPPED Works in installEgoSdk

The SDK follows a three-step wrapping protocol when `installEgoSdk()` executes:

1. **Detect prior installation** – check if `globalThis.ego[EGO_WRAPPED]` exists
2. **Wrap the runtime** – inject helper methods (`page`, `browser`, `taskSpaces`, `site`, `fetch`) from [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts)
3. **Mark as wrapped** – set `globalThis.ego[EGO_WRAPPED] = true` to block re-wrapping

This logic lives in the entry point at [`src/index.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/index.ts), which orchestrates the entire installation flow.

### Preventing Double-Wrapping

Subsequent calls to `installEgoSdk()` encounter the symbol and exit early. This avoids:

- Duplicate event listeners accumulating in memory
- Helper methods being overwritten with stale references
- Inconsistent state between the original `ego` bindings and injected wrappers

## Key Guarantees Provided by EGO_WRAPPED

The symbol enables two architectural guarantees that other modules can rely on:

**Idempotent installation** – the SDK can be required or executed multiple times without side effects. This prevents memory leaks and state corruption in long-running automation scripts.

**Explicit identification** – external code can test `if (globalThis.ego?.[EGO_WRAPPED])` to determine if the full SDK surface is available. This enables conditional polyfills or fallback implementations during unit testing.

## Symbol Implementation Details

`EGO_WRAPPED` is created with `Symbol.for('ego.wrapped')`, making it **unique across realms** yet **shareable** between any code that knows the exact key. Because Symbols are non-enumerable and don't convert to strings, they won't clash with user-defined properties on the `ego` object.

The symbol lives on the same `ego` object that [`src/state.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/state.ts) manipulates as its runtime singleton, ensuring consistent identity across the codebase.

## Practical Code Examples

### Typical SDK Installation

```typescript
// Inside ego-lite entry point or consuming application
import { installEgoSdk } from 'ego-browser';

// The function checks EGO_WRAPPED internally
installEgoSdk();   // adds helpers & marks ego as wrapped

```

### Manual Symbol Check

```typescript
// Useful in test environments for conditional setup
if (globalThis.ego?.[Symbol.for('ego.wrapped')]) {
  console.log('Ego SDK already installed');
}

```

### Guard Pattern Implementation

```typescript
// Replicates the internal logic from installEgoSdk
function safeInstall() {
  const EGO_WRAPPED = Symbol.for('ego.wrapped');
  if (globalThis.ego?.[EGO_WRAPPED]) return; // already wrapped
  
  // ... inject helpers from src/helpers.ts
  
  globalThis.ego[EGO_WRAPPED] = true;
}

```

## Source Files Referenced

| File | Role |
|------|------|
| [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts) | Defines the public helper surface (`page`, `browser`, etc.) attached during installation |
| [`src/index.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/index.ts) | Entry point containing `installEgoSdk()` and the EGO_WRAPPED check/set logic |
| [`src/state.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/state.ts) | Holds the runtime singleton; the symbol lives on this managed `ego` object |

## Summary

- **EGO_WRAPPED** is a Symbol that prevents duplicate SDK installation in ego-lite
- `installEgoSdk()` in [`src/index.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/index.ts) checks this symbol before wrapping `globalThis.ego`
- The mechanism guarantees **idempotent installation** and provides **explicit availability detection**
- Implemented via `Symbol.for('ego.wrapped')` to avoid property collisions
- Referenced across [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts), [`src/index.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/index.ts), and [`src/state.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/state.ts) for consistent runtime management

## Frequently Asked Questions

### What happens if I call installEgoSdk() multiple times?

The function exits immediately on subsequent calls. The EGO_WRAPPED symbol on `globalThis.ego` signals that helpers are already present, so no duplicate injection occurs.

### Can I check for ego-lite availability without importing the SDK?

Yes. Test `globalThis.ego?.[Symbol.for('ego.wrapped')]` from any context. This returns `true` only after `installEgoSdk()` has successfully completed.

### Why use a Symbol instead of a string property?

Symbols are unique, non-enumerable, and immune to accidental overwriting. A string like `ego._wrapped` could conflict with user code or future SDK additions.

### Where is the EGO_WRAPPED symbol actually defined?

The symbol is constructed inline within [`src/index.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/index.ts) using `Symbol.for('ego.wrapped')`, then referenced throughout the installation and detection logic.