DEV Community

Samcorp
Samcorp

Posted on

We Migrated a 12-Year-Old Org to Lightning - Everything That Broke

We Migrated a 12-Year-Old Org to Lightning - Everything That Broke
A twelve-year-old Salesforce org doesn't contain twelve years of configuration.

It contains twelve years of decisions.

Some were documented. Some were temporary fixes that became permanent. Some were created by admins who left years ago. Others were Visualforce pages, JavaScript buttons, old URL patterns, integrations, permission assumptions, and custom workflows that had quietly become business-critical.

That was the real challenge behind our Classic to Lightning migration.

At first, the project sounded simple:

Salesforce Classic
        ↓
Enable Lightning
        ↓
Fix a few pages
        ↓
Train users
        ↓
Done
Enter fullscreen mode Exit fullscreen mode

The actual process looked more like:

Inventory
   ↓
Classify legacy customizations
   ↓
Identify Lightning gaps
   ↓
Modernize critical workflows
   ↓
Test permissions and integrations
   ↓
Roll out gradually
   ↓
Measure adoption
   ↓
Remove remaining Classic dependencies
Enter fullscreen mode Exit fullscreen mode

The migration wasn't primarily a UI upgrade.

It was an archaeology project.


1. The First Thing That Broke Was Our Estimate

We initially counted obvious customizations:

  • Visualforce pages
  • Apex classes
  • Custom objects
  • Workflows
  • JavaScript buttons
  • Integrations

That gave us an inventory.

It did not give us an accurate estimate.

One Visualforce page might be a simple form.

Another might depend on:

Visualforce
+
Custom JavaScript
+
Apex controller
+
URL parameters
+
Profile-specific behavior
+
External API
Enter fullscreen mode Exit fullscreen mode

Both count as one page.

They are completely different migration tasks.

We stopped estimating by component count and started asking:

Which business workflow depends on this customization?

That produced a much more realistic migration plan.


2. We Inventoried Behavior, Not Just Metadata

A long-lived Salesforce org can contain technically valid metadata that nobody actively understands.

We classified important customizations as:

KEEP
MIGRATE
REPLACE
REMOVE
INVESTIGATE
Enter fullscreen mode Exit fullscreen mode

For each one, we asked:

Who uses it?

Which profiles or permission sets need it?

Which record types depend on it?

Does it invoke Apex?

Does it depend on Classic navigation?

Does an integration call it?

What happens if we remove it?
Enter fullscreen mode Exit fullscreen mode

That final question uncovered several supposedly unused features.

They were not unused.

They were simply used rarely.

That distinction matters in a migration.


3. JavaScript Buttons Were an Early Warning

Classic-era JavaScript buttons often hide far more business logic than their UI suggests.

A button labeled:

Create Renewal
Enter fullscreen mode Exit fullscreen mode

might actually:

Read current record
      ↓
Validate fields
      ↓
Build parameters
      ↓
Navigate to another page
      ↓
Trigger downstream automation
Enter fullscreen mode Exit fullscreen mode

The button looked simple.

The implementation was effectively a small application.

Moving to Lightning forced us to decide whether each behavior should become:

Quick Action
Flow
Lightning Web Component
Apex-backed action
Standard Salesforce functionality
Enter fullscreen mode Exit fullscreen mode

The positive part was that we stopped carrying forward old JavaScript simply because it already existed.

Migration became an opportunity to move critical business behavior into cleaner, supported platform patterns.


4. URL Hacks Had to Be Treated as Technical Debt

Classic-era implementations often accumulate hard-coded URL assumptions.

Conceptually:

/001/e?someParameter=value
Enter fullscreen mode Exit fullscreen mode

or custom navigation logic that depends on a specific page structure.

These patterns can become fragile when the experience changes.

So we searched more than code.

We reviewed:

  • Buttons
  • Links
  • Visualforce
  • JavaScript
  • Apex-generated URLs
  • Email templates
  • Integration responses
  • Internal documentation

This produced one of the recurring lessons of the Classic to Lightning migration:

A UI migration can break code that doesn't look like UI code.


5. Visualforce Didn't Automatically Mean "Rewrite It"

The right question wasn't:

Do we have Visualforce?

It was:

How does this particular Visualforce page behave inside Lightning?

Some pages could continue working usefully.

Others exposed problems involving:

  • Navigation
  • Styling
  • JavaScript assumptions
  • Page dimensions
  • Modal behavior
  • Record context
  • Browser behavior

Instead of rewriting everything, we classified each page.

Visualforce page
       ↓
Still useful and compatible?
       ├── YES → Keep temporarily
       │
       └── NO
            ↓
        Modern replacement
Enter fullscreen mode Exit fullscreen mode

That kept the project focused on real risk instead of creating unnecessary development work.


6. We Didn't Rewrite Everything to LWC

Once Lightning Web Components entered the discussion, another tempting strategy appeared:

Rewrite every customization.

That would have dramatically increased scope without necessarily improving the business outcome.

Instead, we asked:

Does this component genuinely need replacement?

Is it business-critical?

Is the current implementation difficult to maintain?

Is the workflow changing anyway?

Can standard Salesforce functionality now replace it?
Enter fullscreen mode Exit fullscreen mode

For older orgs, Salesforce migration and modernization is broader than replacing Visualforce or Aura with LWC. It can also involve reviewing Apex, integrations, permissions, testing practices, deployment workflows, and technical debt before deciding what should actually be rebuilt.

Our target became:

Minimum custom code
+
Supported platform patterns
+
Required business behavior
Enter fullscreen mode Exit fullscreen mode

rather than:

Maximum amount of new Lightning code
Enter fullscreen mode Exit fullscreen mode

That kept the migration more controlled.


7. Record Pages Changed More Than the Look

Classic encouraged us to think primarily in terms of page layouts.

Lightning introduced a broader record-page experience.

A user might now interact with:

Record details
Tabs
Related lists
Custom components
Highlights
Activity
Conditional visibility
Utility components
Enter fullscreen mode Exit fullscreen mode

That flexibility is valuable.

It also makes it easy to build pages that do too much.

Our first Lightning pages were too heavy because we tried to put every useful component in one place.

We started asking:

Does every user need this component?

Does it need to load immediately?

Can it live behind a tab?

Can standard functionality replace it?

Is this Apex call actually necessary?
Enter fullscreen mode Exit fullscreen mode

A good Lightning page isn't the page with the most features.

It is the page that helps the user complete the next task quickly.


8. Permissions Exposed Hidden Assumptions

Testing only as System Administrator gave us false confidence.

Admin testing said:

It works.
Enter fullscreen mode Exit fullscreen mode

Real users said:

I can't see it.
Enter fullscreen mode Exit fullscreen mode

or:

I can see it, but I can't use it.
Enter fullscreen mode Exit fullscreen mode

The difference often came from:

  • Object permissions
  • Field-level security
  • Apex access
  • Record types
  • Permission sets
  • App access
  • Component visibility
  • Custom permissions

So we created explicit test personas:

Sales Rep
Sales Manager
Service Agent
Operations
Finance
Administrator
Integration User
Enter fullscreen mode Exit fullscreen mode

Every critical workflow had to work with the permissions of the person who actually performs it.


9. Navigation Was Part of the Business Process

Long-time users had muscle memory.

They knew:

Click tab
Open list
Choose view
Open record
Click button
Enter fullscreen mode Exit fullscreen mode

Lightning sometimes changed that path.

At first, this looked like a training problem.

Sometimes it was.

Other times it revealed processes that had always been inefficient but had become familiar.

Instead of reproducing every Classic click path, we asked:

What is the user actually trying to accomplish?

That led to better navigation design and cleaner user workflows.


10. Integrations Needed Testing Too

Some backend integrations using Salesforce APIs were largely unaffected by the UI change.

Others were not.

Over twelve years, external systems may begin relying on assumptions about:

URLs
Rendered pages
Authentication flow
Record creation sequence
Browser redirects
Button behavior
Enter fullscreen mode Exit fullscreen mode

So our integration inventory included:

  • REST and SOAP integrations
  • Middleware
  • Connected apps
  • Scheduled jobs
  • Browser automation
  • Email-driven processes
  • Webhooks
  • Apex callouts
  • External links

The lesson was simple:

Classic-to-Lightning testing should not involve only admins and frontend developers.

Anything connected to a business workflow deserves regression testing.


11. Reports and Dashboards Needed Cleanup

Reports didn't necessarily break because the UI changed.

But migration gave us a reason to review which reports still mattered.

A twelve-year-old org can easily contain:

Sales Pipeline
Sales Pipeline New
Sales Pipeline V2
Sales Pipeline Final
Sales Pipeline FINAL USE THIS
Enter fullscreen mode Exit fullscreen mode

We reviewed:

  • Critical reports
  • Dashboard visibility
  • Folder permissions
  • Filters
  • Subscriptions
  • Drill-down behavior
  • Links from other workflows

Not every piece of historical configuration needed to become part of the new experience.

Migration was also a cleanup opportunity.


12. Some Features Were Different, Not Broken

One important mindset shift was accepting that Lightning does not need to behave exactly like Classic.

The wrong question is:

How do we recreate the exact Classic workflow?

A better question is:

What is the supported Lightning way to achieve the same business outcome?

Sometimes the implementation is different.

That is fine.

A migration should preserve business behavior.

It does not need to preserve every historical technical decision.


13. We Used Sandboxes as Migration Laboratories

Production users should not be the first people to discover compatibility issues.

Our cycle became:

Inventory
   ↓
Configure or modernize
   ↓
Deploy to sandbox
   ↓
Test workflows
   ↓
Test user roles
   ↓
Collect feedback
   ↓
Fix
   ↓
Repeat
Enter fullscreen mode Exit fullscreen mode

This was especially valuable for:

  • Visualforce
  • Lightning pages
  • Apex
  • Flows
  • Custom actions
  • Permissions
  • Integrations
  • Navigation

The goal was for production rollout to become increasingly uneventful.

That is generally a good sign.


14. We Rolled Out by User Group

A twelve-year-old Salesforce org has different types of users.

Sales may use Salesforce all day.

Finance may use only a handful of workflows.

Operations might depend heavily on a few deeply customized screens.

So instead of:

Migration day
→ Everyone switches
Enter fullscreen mode Exit fullscreen mode

we used:

Migration team
      ↓
Power users
      ↓
Pilot department
      ↓
Additional teams
      ↓
Broader rollout
Enter fullscreen mode Exit fullscreen mode

This helped us separate:

Actual defect
Missing functionality
Permission issue
Training problem
Preference for Classic
Enter fullscreen mode Exit fullscreen mode

Those are very different issues and need different responses.


15. User Adoption Became a Technical Signal

If users kept returning to Classic, we didn't immediately conclude:

They don't like change.

We investigated.

Maybe:

One workflow is missing

A page is too slow

An action is difficult to find

Permissions are wrong

Training missed a scenario

A Classic dependency still exists
Enter fullscreen mode Exit fullscreen mode

User behavior became another source of migration telemetry.

If users had a legitimate reason to return to Classic, the migration was not finished.


16. The Migration Workflow That Worked Better

Eventually, our process became:

1. Inventory critical business workflows

2. Identify who uses each workflow

3. Map Classic customizations and dependencies

4. Classify each item:
   Keep / Migrate / Replace / Remove

5. Build representative user personas

6. Design Lightning pages intentionally

7. Modernize only where needed

8. Test integrations and automation

9. Test every critical workflow by role

10. Pilot with real users

11. Fix defects and usability gaps

12. Expand rollout

13. Monitor adoption

14. Remove remaining Classic dependencies
Enter fullscreen mode Exit fullscreen mode

A structured Salesforce Classic to Lightning migration should begin with an org audit covering Visualforce, Aura, JavaScript buttons, hard-coded URLs, permissions, integrations, and role-specific workflows before the actual rollout begins.

That planning work matters far more than simply enabling Lightning.


What Actually Took the Time

Looking back, the project was not:

Enable Lightning
+
Fix Visualforce
Enter fullscreen mode Exit fullscreen mode

It was:

Understand twelve years of behavior
        ↓
Classify customizations
        ↓
Identify unsupported assumptions
        ↓
Modernize high-risk workflows
        ↓
Redesign important pages
        ↓
Revalidate permissions
        ↓
Retest integrations
        ↓
Test by role
        ↓
Train users
        ↓
Measure adoption
        ↓
Remove remaining Classic dependencies
Enter fullscreen mode Exit fullscreen mode

The UI change was the visible part.

The dependency cleanup underneath it was the real migration.


A Practical Classic to Lightning Migration Checklist

Before rollout:

[ ] Critical workflows inventoried

[ ] Visualforce pages reviewed

[ ] JavaScript buttons reviewed

[ ] Classic URL assumptions reviewed

[ ] Custom navigation reviewed

[ ] Lightning pages intentionally designed

[ ] Heavy pages profiled

[ ] Apex-backed components tested

[ ] Integrations regression-tested

[ ] Profiles and permission sets reviewed

[ ] Field-level security tested

[ ] Reports and dashboards validated

[ ] Representative user personas defined

[ ] Role-based UAT completed

[ ] Training covers real workflows
Enter fullscreen mode Exit fullscreen mode

After rollout:

[ ] Adoption monitored

[ ] Remaining Classic usage investigated

[ ] User feedback categorized

[ ] Performance issues measured

[ ] Missing workflows addressed

[ ] Redundant customizations removed

[ ] Dead reports/components cleaned up

[ ] Classic dependencies reduced

[ ] Classic access restricted when appropriate
Enter fullscreen mode Exit fullscreen mode

The Biggest Lesson

The biggest surprise wasn't simply that things broke.

It was what broke.

We expected:

Visualforce
Custom JavaScript
Old components
Enter fullscreen mode Exit fullscreen mode

We also found:

User habits
Navigation assumptions
Permission assumptions
Integration assumptions
Reporting clutter
Page-performance issues
Undocumented workflows
Years of technical debt
Enter fullscreen mode Exit fullscreen mode

That is why migrating a twelve-year-old Salesforce org is not simply a user-interface project.

It is an opportunity to ask:

Which parts of the last twelve years still deserve to exist?

We didn't want Lightning to become:

Classic
+
new interface
+
all existing technical debt
Enter fullscreen mode Exit fullscreen mode

We wanted:

Required business behavior
+
cleaner supported patterns
+
simpler pages
+
better-understood permissions
+
tested integrations
+
fewer legacy dependencies
Enter fullscreen mode Exit fullscreen mode

A successful Classic to Lightning migration was not the moment Lightning was enabled.

It was the moment users could complete their work confidently in Lightning without having a business reason to return to Classic.


Top comments (0)