# How to Build ego-lite from Source: Complete Step-by-Step Guide for Browser Automation

> Learn how to build ego-lite from source with this step-by-step guide. Get your browser automation script ready by following simple Node npm install and build commands.

- Repository: [CitroLabs/ego-lite](https://github.com/citrolabs/ego-lite)
- Tags: how-to-guide
- Published: 2026-08-03

---

**Building ego-lite from source requires Node ≥22, runs `npm install` followed by `npm run build`, and produces a bundled CLI at [`dist/out/index.js`](https://github.com/citrolabs/ego-lite/blob/main/dist/out/index.js) ready for browser-automation scripting.**

ego-lite is an open-source browser-automation harness written in TypeScript. This guide walks through compiling the TypeScript sources, bundling the CLI with **esbuild** and **rollup**, embedding generated help documentation, and copying the `ego-browser` skill assets into the distribution folder. The entire process is driven by the build script at `package/ego-browser/scripts/build.mjs`.

## Prerequisites for Building ego-lite

Before starting, verify your environment meets the requirements specified in [`package/ego-browser/package.json`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/package.json).

### Node.js Version Requirement

ego-lite requires **Node ≥22** as declared in the `engines` field:

```json
// package/ego-browser/package.json
"engines": {
  "node": ">=22"
}

```

Check your version:

```bash
node -v   # should print >=22.x.x

```

## Step 1: Clone the Repository and Install Dependencies

Clone the citrolabs/ego-lite repository and navigate to the package directory:

```bash
git clone https://github.com/citrolabs/ego-lite.git
cd ego-lite/package/ego-browser

```

Install all development and runtime dependencies:

```bash
npm ci   # or npm install

```

This pulls in **TypeScript**, **esbuild**, **rollup**, and the runtime dependency **acorn** as listed in [`package.json`](https://github.com/citrolabs/ego-lite/blob/main/package.json) lines 26–40.

## Step 2: Run the Build Script

Execute the npm build shortcut, which triggers `node scripts/build.mjs`:

```bash
npm run build

```

The build script orchestrates seven distinct phases, each implemented in `package/ego-browser/scripts/build.mjs`:

### 2.1 Acquire Build Lock

Prevents concurrent builds by creating `.build.lock` (lines 34–42).

### 2.2 Clean Previous Output

Deletes `dist/`, `artifacts/`, and temporary files (lines 44–49).

### 2.3 Compile TypeScript with esbuild

Transpile every `*.ts` file under `scripts/` and `src/` (lines 58–66):

```javascript
// From build.mjs — esbuild compilation
await esbuild.build({
  entryPoints: tsFiles,
  outdir: 'artifacts',
  format: 'esm',
  platform: 'node',
  target: 'node22',
  bundle: false,  // individual files first
  sourcemap: true,
})

```

### 2.4 Bundle the CLI with rollup

rollup bundles [`src/index.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/index.ts) into a single ESM file at [`dist/out/index.js`](https://github.com/citrolabs/ego-lite/blob/main/dist/out/index.js) (lines 68–84).

### 2.5 Copy Skill Assets

The `ego-browser` skill directory (`skills/ego-browser`) is copied into `dist/out/ego-browser` (lines 88–90).

### 2.6 Make CLI Executable

Sets the Unix executable bit on [`dist/out/index.js`](https://github.com/citrolabs/ego-lite/blob/main/dist/out/index.js) (lines 90–91).

### 2.7 Embed Help Documentation

The `embedHelpDocs` function extracts JSDoc help strings via `extract-help-docs.mjs` and injects them into runtime files, replacing the placeholder `__EGO_EMBEDDED_HELP_DOCS__` (lines 96–119).

### 2.8 Release Build Lock

Removes the lock file, allowing future builds (lines 91–94).

## Step 3: Verify the Build (Optional)

Run the test suite to confirm everything works:

```bash
npm test

```

## Using the Built ego-lite CLI

After `npm run build` completes, the compiled CLI is available at [`dist/out/index.js`](https://github.com/citrolabs/ego-lite/blob/main/dist/out/index.js) and installed as the npm binary `ego-browser` (see `bin` field in [`package.json`](https://github.com/citrolabs/ego-lite/blob/main/package.json) lines 6–8).

### Direct Execution

```bash
node dist/out/index.js <<'JS'
await page.goto("https://example.com");
console.log(await page.title());
JS

```

### Using the Global Binary

```bash
ego-browser <<'JS'
await page.goto("https://example.com");
console.log(await page.title());
JS

```

These snippets demonstrate the **runtime helpers** (`page`, `browser`, `taskSpaces`, `site`, `fetch`) exported from `helperContext` defined in [`package/ego-browser/src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/helpers.ts). This helper façade is the core API surface used by agents and user scripts.

## Key Source Files in the Build Process

| File | Role |
|------|------|
| [`package/ego-browser/package.json`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/package.json) | Declares scripts, dependencies, Node version, and binary entry point |
| `package/ego-browser/scripts/build.mjs` | Orchestrates compilation, bundling, and asset-copying |
| [`package/ego-browser/src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/helpers.ts) | Exposes public API (`page`, `browser`, `taskSpaces`, etc.) |
| [`package/ego-browser/src/run.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/run.ts) | Entry point for executing user scripts inside helper context |
| [`package/ego-browser/src/state.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/state.ts) | Holds shared mutable runtime state (timeouts, workspace location) |
| [`package/ego-browser/src/help-runtime.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/help-runtime.ts) | Parses JSDoc at runtime to provide `help()` function |
| `package/ego-browser/skills/ego-browser/` | Skill manifest and site-specific learning packs |
| `package/ego-browser/dist/out/` | Generated output with bundled CLI and skill assets |

## Summary

Building ego-lite from source follows a clear pipeline:

- **Node ≥22** is mandatory — enforced by `engines` field in [`package.json`](https://github.com/citrolabs/ego-lite/blob/main/package.json)
- **`npm install`** pulls esbuild, rollup, TypeScript, and acorn dependencies
- **`npm run build`** executes `scripts/build.mjs` which: acquires lock, cleans output, compiles TypeScript, bundles with rollup, copies skills, makes executable, embeds help docs, releases lock
- **Output** lands at [`dist/out/index.js`](https://github.com/citrolabs/ego-lite/blob/main/dist/out/index.js) with the `ego-browser` binary ready for browser-automation scripting
- **Runtime helpers** in [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts) provide the `page`, `browser`, `taskSpaces`, `site`, and `fetch` APIs

## Frequently Asked Questions

### What Node version is required to build ego-lite?

ego-lite requires **Node ≥22** as specified in the `engines` field of [`package/ego-browser/package.json`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/package.json). The build will fail on earlier versions. Run `node -v` before starting to verify compatibility.

### What build tools does ego-lite use?

ego-lite uses **esbuild** for fast TypeScript transpilation and **rollup** for creating the final bundled CLI. These are invoked sequentially by `scripts/build.mjs` — esbuild handles the initial compilation, then rollup produces the single ESM output file.

### Where does the built CLI get installed?

After `npm run build`, the executable resides at [`package/ego-browser/dist/out/index.js`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/dist/out/index.js). npm also registers `ego-browser` as a global binary (via the `bin` field), so you can invoke it directly after installation with `npm link` or when running from the package directory.

### Why does the build embed help documentation?

The `embedHelpDocs` step extracts JSDoc comments from the bundled code and injects them into runtime files. This replaces the `__EGO_EMBEDDED_HELP_DOCS__` placeholder, enabling the `help()` function to provide accurate documentation without requiring source files at runtime.