When we tell a CTO we convert PL/SQL to TypeScript, the first reaction is usually fear. “You’re rewriting our business logic?” No. We’re translating it. The distinction is the entire point.
A rewrite means a developer reads the PL/SQL, forms a mental model of what it should do, and writes new code from scratch. That’s where bugs appear. That’s where the Australian GST exemption added in 2014 quietly disappears. A translation means the system reads the PL/SQL, identifies structural patterns, and emits equivalent TypeScript that implements identical behavior. The logic survives. The language changes. The architecture improves.
What changes
The runtime. PL/SQL executes inside the Oracle Database. TypeScript executes in Node.js or the browser. That single shift unlocks API exposure, horizontal scaling, and containerized deployment — three capabilities the database engine was never designed to provide.
The type system. PL/SQL types map cleanly. NUMBER becomes number. VARCHAR2 becomes string. DATE becomes Date. Record types become interfaces. The mapping is mechanical, not interpretive.
The error handling. PL/SQL exceptions become structured try/catch blocks. RAISE_APPLICATION_ERROR becomes typed error responses with HTTP status codes that downstream systems can actually consume.
The data access. Embedded SQL becomes API calls. SELECT FROM contractors WHERE... becomes this.api.getContractors(filters). The query still hits the same Oracle tables, but through a governed REST layer rather than direct database coupling.
What stays the same
Every validation rule. If the PL/SQL requires a positive amount, the TypeScript does too.
Every calculation. If the PL/SQL computes tax as amount * rate / 100, the TypeScript performs identical arithmetic to identical precision.
Every conditional branch. If the PL/SQL has CASE WHEN status = 'APPROVED' THEN..., the TypeScript carries the same conditional structure.
Every workflow step. If orders over $50K need VP approval before status can change, the new code enforces the same gate. The behavior is identical because the rules are identical.
What the migration unlocks
The new architecture isn’t just a language swap. It enables capabilities Oracle Forms never could:
- Unit testing. Each validation becomes an independently testable function. Forms made meaningful test coverage nearly impossible.
- Version control. The TypeScript lives in Git. Every change has a commit, an author, and a diff. PL/SQL inside .fmb files had none of that.
- API exposure. Logic that was trapped inside the database becomes callable from mobile apps, partner systems, or AI agents.
- Parallel development. Multiple engineers work different modules simultaneously without stepping on each other’s files.
The honest caveats
Does every line translate cleanly? No. Oracle Forms has quirks — implicit commits, navigator-driven screen flow, canvas-coordinate positioning — that don’t have direct modern equivalents. Those require architectural decisions during migration, and we make them deliberately.
But the core business logic — the rules, calculations, validations, and workflows the company actually depends on — translates reliably. Math is math. A constraint on a credit limit is a constraint on a credit limit, regardless of which language enforces it.