The modernization is the foundation. The transformation is what you build on top of it.

A successfully executed PowerBuilder modernization is not a destination. It is the moment everything that was structurally impossible becomes possible.

The API-first backend now serves multiple surfaces simultaneously — a web application, a mobile app, a partner integration, a data pipeline. With the original PowerBuilder runtime, each of those would have required a separate architecture. Now they share one.

Performance becomes optimizable. The original application likely retrieved entire DataWindow result sets to the client before filtering at the display layer. The modernized system pushes filtering and aggregation into the database or a Redis caching layer. Expensive computed queries run once and are cached. Reports that took minutes take seconds.

Security posture transforms. The original system ran on a corporate network with implicit trust. The modernized system enforces OAuth 2.0 authentication at every API boundary, supports multi-factor authentication, generates a full audit trail at the service layer, and integrates with enterprise SIEM tooling. This is not a patch — it is a structural improvement.

Recruiting becomes normal. Any competent .NET or React developer can maintain and extend the system. You are no longer searching for a specialist who remembers what PowerScript looks like. The talent pool goes from a handful of senior developers to every software engineer in your market.

None of this is an add-on. It is what you get when the business logic — the actual asset — runs in a modern runtime rather than a proprietary one.

The modernization is the foundation. The transformation is what you build on top of it.

 

You can find relevant information in the specific section: https://enable-dev.com/modernization

Follow us on LinkedIn.

“How do we know the new system is correct?”

“How do we know the new system is correct?”
Ā 
That question gets asked in every modernization project. The wrong answer is: “We’ll test it.” The right answer is a methodology, not a promise.
Parallel running is that methodology.
Ā 
Here is how it works in practice:
Phase 1 — regression harness before migration begins. An automated test harness drives both the original PowerBuilder application and the new API with identical inputs and compares their outputs — retrieve results, computed column values, validation outcomes. Every divergence is a defect. No module moves forward until outputs match completely.
Phase 2 — shadow mode in production. As each module is migrated, a subset of real production transactions is processed by both systems simultaneously. The legacy system’s output is authoritative. The new system runs alongside it, silent, proving its behavior under conditions no test environment fully replicates.
Phase 3 — gradual promotion. Only when a module is demonstrably stable in shadow mode — with zero divergence over a meaningful transaction volume — does it get promoted to primary status and its legacy equivalent retired.
Ā 
The result: a cutover that is never a single event.
Each module earns its promotion individually.
No single night when everything is at risk
Ā 
Parallel running is not a precaution. It is the only systematic proof that the migration worked.

 

You can find relevant information in the specific section: https://enable-dev.com/modernization

Follow us on LinkedIn.

Before a single line of new code is written, you need to know exactly what you are dealing with.

Before a single line of new code is written, you need to know exactly what you are dealing with.
Not approximately.
Precisely.
Ā 
This is the discovery phase — and skipping it is the most expensive mistake a PowerBuilder modernization program can make.
Ā 
Here is what a rigorous discovery produces:
Step 1 — Export and parse all .pbl libraries. Every DataWindow object, window, function, and global variable catalogued programmatically. Automated tools do this in hours, not weeks.
Step 2 — Categorize by type and complexity. Standard retrieval DataWindows. Composite reports. Dynamic DataWindows that use Modify() at runtime. Nested structures. Each category carries a different migration risk profile.
Step 3 — Build the dependency graph. Which DataWindows are used by which windows. Which windows are called from which menus. This is the map that tells you which modules can migrate first and which must wait.
Step 4 — Identify high-risk objects. Computed columns with complex expressions. DataWindows that have been modified dozens of times. Objects whose behavior is inferrable only from institutional memory or production observation.
Step 5 — Produce the effort model. Module by module, based on actual complexity data. This is the document a project sponsor can plan against — not a guess, not a range, a structured estimate.
Ā 
Discovery is not overhead. It is the foundation that makes everything downstream reliable.

 

You can find relevant information in the specific section: https://enable-dev.com/modernization

Follow us on LinkedIn.

The target architecture for a modernized PowerBuilder application is a clean three-tier system

The target architecture for a modernized PowerBuilder application is a clean three-tier system.

Tier 1 — the frontend: A React or Angular single-page application, served from a CDN. Fully responsive — works on a 375px phone screen, a tablet, and also a widescreen monitor. Furthermore communicates with the backend exclusively through HTTPS API calls. A React Native or Flutter app shares the same API surface for mobile.

Tier 2 — the service layer: An ASP.NET Core application, containerized, deployed in Kubernetes or Azure App Service. Hosts a versioned REST API secured with OAuth 2.0. Each controller maps to a functional domain — accounts, orders, reporting — and internally uses .NET DataStore objects to execute the business logic originally contained in PowerBuilder DataWindows. Secured with JWT, fine-grained authorization via ASP.NET Core policies.

Tier 3 — the database: Preserved as-is during the initial migration to ensure continuity. The existing relational database — SQL Server, Oracle, DB2 — continues as the system of record. Schema changes are introduced once the application layer reaches stability.

Three properties make this architecture compelling:

It is incremental — individual DataWindow objects migrate one at a time while the rest continue running in the legacy application.

It’s verifiable — the DataStore and the original app run against the same inputs, with outputs compared automatically.

It’s evolvable — once logic runs in .NET, it can be refactored into handwritten C# service classes wherever business value justifies it.

 

You can find relevant information in the specific section: https://enable-dev.com/modernization

Follow us on LinkedIn.

How do you actually preserve DataWindow logic in a .NET world?

The question every tech lead asks: “How do you actually preserve DataWindow logic in a .NET world?”

The answer is .NET DataStore — a NuGet package that brings DataWindow semantics into the .NET runtime.

 

What it does:

-> Reads DataWindow definitions exported from the PB application

-> Executes the embedded SQL against the target database

-> Evaluates computed column expressions

-> Applies validation rules and formats output

 

From C#, it exposes Retrieve(), Update(), GetItemString(), SetItem() — familiar to anyone who knows PowerScript, inside idiomatic C# code.

An ASP.NET Core API wraps the DataStore. A React frontend consumes the API. The frontend knows nothing about PowerBuilder.

The result: a modern web application backed by the same business logic that has served the organization for decades. Verified. Tested. Running in parallel until every output matches.

 

You can find relevant information in the specific section: https://enable-dev.com/modernization

Follow us on LinkedIn.

We've never lost a business rule. Not one.

Before you approve a rewrite budget, talk to us first. A free 30-minute technical scoping call could save you years.

Book a free scoping call →