ego-lite CLI Mode vs SDK Mode: Key Differences Explained
ego-lite operates in two distinct modes: CLI mode for stand-alone command execution via runMain() and SDK mode for library integration via installEgoSdk(), differing primarily in invocation method, entry-point detection, and process lifecycle.
The citrolabs/ego-lite repository provides a flexible browser automation tool that adapts its behavior based on how it is invoked. Understanding the distinction between ego-lite CLI mode and SDK mode is essential for choosing the right integration approach for your automation workflows.
How Each Mode Is Invoked
The fundamental difference begins with how you access the library's functionality.
CLI mode is triggered when you execute ego-lite as a stand-alone command. The binary reads JavaScript from stdin and immediately runs it:
ego-browser <<'JS'
await page.goto('https://example.com')
console.log(await page.title())
JS
SDK mode requires importing the package as a module and explicitly installing the helpers onto a target object, typically globalThis:
import { installEgoSdk } from "ego-browser";
installEgoSdk(); // installs helpers on globalThis
await page.goto('https://example.com');
console.log(await page.title());
Entry Point Detection Logic
In src/index.ts, ego-lite determines which mode to activate by inspecting process.argv[1]. If the current process matches the bundled index.js path, the code invokes runMain() to enter CLI mode【/cache/repos/github.com/citrolabs/ego-lite/main/package/ego-browser/src/index.ts#L75-L78】.
When this detection fails—meaning the package was imported as a module rather than executed directly—the fallback automatically calls installEgoSdk()【/cache/repos/github.com/citrolabs/ego-lite/main/package/ego-browser/src/index.ts#L64-L66】. This conditional branching ensures the correct initialization path without requiring manual configuration flags.
Primary Purpose and Use Cases
Each mode serves distinct automation needs.
CLI mode provides a command-line interface designed for quick one-off scripts. It handles argument parsing for flags like --help, --doctor, and --reload, then reads the script body from stdin. The implementation lives in runMain() within src/run.ts, which orchestrates argument handling, context creation, and execution flow.
SDK mode exposes the full browser-automation API—including page.goto, waitForSelector, and task-space APIs—as properties on the target object. This allows Node programs or libraries to embed ego-lite without spawning separate CLI processes, making it ideal for test harnesses, custom automation frameworks, or applications requiring programmatic control.
Output Handling Differences
Both modes buffer console.log output, but they manage sinks differently.
In CLI mode, src/run.ts implements a per-run output sink using resetSink() and flushSink(). The runtime buffers all logs during execution and flushes them when the script finishes, ensuring clean terminal output for short-lived processes.
In SDK mode, the sink behavior depends on the host configuration. When installEgoSdk() executes, it checks whether the host supplies a custom cliLog function. If not, it sets usingDefaultLog to true and uses the default buffered sink【/cache/repos/github.com/citrolabs/ego-lite/main/package/ego-browser/src/index.ts#L75-L82】. The sink resets only when the host explicitly provides logging overrides, allowing persistent buffers across multiple SDK calls.
Process Lifecycle
The operational lifespan differs significantly between modes.
CLI mode runs in a short-lived Node process. After runMain() completes the script execution and flushes the output sink, the process exits immediately. This matches the ephemeral nature of command-line tools.
SDK mode persists for the lifetime of the host process. Once installEgoSdk() attaches helpers to globalThis or another target object, the installation remains active, allowing multiple scripts or API calls to share the same runtime state and browser instance.
Shared Infrastructure
Despite their different entry points, both modes leverage common internal modules:
src/helpers.tsprovideshelperContext(), ensuring CLI and SDK paths expose identical browser-automation surfacessrc/output-sink.tsmanages buffered logging viabufferOutput,resetSink, andflushSinkfor both modessrc/browser-runtime.tscontains runtime utilities that underpin helper functions regardless of invocation method
Summary
- ego-lite CLI mode executes via
runMain()insrc/run.ts, reads scripts from stdin, processes arguments like--doctor, and exits after flushing buffered output - ego-lite SDK mode activates via
import { installEgoSdk }, attaches helpers toglobalThis, and persists for the host process lifetime - Entry detection occurs in
src/index.tsby checkingprocess.argv[1]against the bundled script path - CLI mode suits ad-hoc terminal automation; SDK mode suits embedded library usage and programmatic control
- Both modes share
src/helpers.tsandsrc/output-sink.tsfor consistent API surfaces and logging behavior
Frequently Asked Questions
How does ego-lite detect whether to run in CLI or SDK mode?
The detection logic in src/index.ts compares process.argv[1] against the bundled index.js path. If they match, the code calls runMain() to initiate CLI mode; otherwise, it automatically invokes installEgoSdk() to enter SDK mode【/cache/repos/github.com/citrolabs/ego-lite/main/package/ego-browser/src/index.ts#L75-L78】.
Can I use ego-lite in SDK mode without polluting globalThis?
Yes. While installEgoSdk() typically installs helpers on globalThis, you can pass a custom target object as an argument to isolate the SDK installation to a specific namespace, preventing global scope pollution in your application.
What happens to console output in CLI mode versus SDK mode?
CLI mode buffers output in a per-run sink implemented in src/run.ts and flushes it when the script terminates. SDK mode also buffers logs, but the sink management depends on whether you provide a custom cliLog function; without one, it uses the default buffered sink that persists across calls【/cache/repos/github.com/citrolabs/ego-lite/main/package/ego-browser/src/index.ts#L75-L82】.
Is there a performance difference between CLI and SDK mode?
CLI mode incurs process startup overhead for each invocation because it spawns a new Node process via runMain(). SDK mode avoids this overhead by remaining resident in memory after installEgoSdk() initializes, making it more efficient for scenarios requiring multiple sequential browser operations.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →