READY
Build: v2.0.0
Migration.md Architecture.ts API.d.ts
NEW Now with 100% more Type Safety

Codex WebUI
TypeScript Edition

The "Reddit-Approved" rewrite. Modular architecture, zero `any` types, and robust state management. It's the same zero-dependency philosophy, just grown up.

src/services/codex.ts
interface SessionState {
  proc: ChildProcess | null;
  resumePath: string;
  memory: string[];
}

// No more spaghetti code.
export class CodexService {
  private state: SessionState;
  /* ...robust logic... */
}

Chapter 10: The Migration Migraine

It started with a single Reddit comment: "Seeing vanilla JS in 2025 hurts my soul."

I looked at my single-file server.js monolith. I looked at the lack of types. I looked at my rubber duck.

"It's just adding types," I said. "How hard can it be?"

48 hours later, fueled by caffeine and spite, the codebase was reborn. No more any. No more guesswork. Just pure, compiled, strict-mode glory.

Sep 09, 2025
Initial Release (Vanilla JS)
Oct 20, 2025
The "Reddit Comment" Incident
Nov 23, 2025
v2.0.0 TypeScript Rewrite
feat: migrate to typescript
feat: add docker support
chore: remove 'any' types

Modular Architecture

From Monolith to Micro-Services (Internal)

Project Structure

src/
server.ts // Entry Point
services/
codex.ts
memory.ts
utils/
config.ts
rate-limit.ts
ARCHITECTURE

Select a Component

Hover over the file tree on the left to inspect the responsibilities of each module in the new TypeScript architecture.

Lines of Code
--
Complexity
--

v2.0 Feature Specification

Docker Containerization

Includes a multi-stage `Dockerfile` based on `node:18-alpine`. Build, ship, and run anywhere without environment headaches.

CI/CD Pipeline

GitHub Actions workflows added for Linting, Building, and Testing on every push. Quality assurance is automated.

Data Portability

Export chat transcripts to JSON. Import previous sessions. Your data is yours, now more portable than ever.

Legacy (v1.0)

function startCodex(path) {
  // What is path? String? Object?
  // Who knows! 
  // Hope it doesn't crash.
  child = spawn('codex', [path]);
  
  child.stdout.on('data', (d) => {
     // Implicit any everywhere...
  });
}

Modern (v2.0)

interface CodexOptions {
  resumePath: string;
  model: ModelType;
}

public start(opts: CodexOptions): void {
  if (!fs.existsSync(opts.resumePath)) {
    throw new Error('Invalid Path');
  }
  // Fully typed process handling
}