---
title: "Visualforce remoting, and what replaced it"
url: "https://trailassembly.com/apex-visualforce-remoting/"
topic: "Apex and Development"
published: "2026-09-18T07:26:36+00:00"
updated: "2026-10-06T13:57:54+00:00"
---

# Visualforce remoting, and what replaced it

**The short version:** JavaScript remoting is a way to call a static Apex method from a Visualforce page without a postback and without view state, and Remote Objects is a declarative way to do basic record CRUD from JavaScript with no Apex at all. Both still work and neither is getting attention. For anything new, Lightning Web Components with wire adapters and `@AuraEnabled` Apex do the same job better. The reason to know these is that plenty of orgs still run them, and somebody has to maintain that code.

## JavaScript remoting, in shape

Mark a static method `@RemoteAction` and call it from the page’s JavaScript with a generated proxy.

```apex
global with sharing class AccountRemoter {
    @RemoteAction
    global static List<Account> search(String term) {
        String like = '%' + String.escapeSingleQuotes(term) + '%';
        return [
            SELECT Id, Name, Industry FROM Account
            WHERE Name LIKE :like WITH USER_MODE LIMIT 25
        ];
    }
}
```

```apex
Visualforce.remoting.Manager.invokeAction(
    '{!$RemoteAction.AccountRemoter.search}',
    term,
    function (result, event) {
        if (event.status) {
            render(result);
        } else {
            console.error(event.message);
        }
    },
    { escape: true, timeout: 30000 }
);
```

The method must be static. It gets no access to page controller state, so everything it needs comes in as arguments. The callback receives the deserialised return value and an event object whose `status` is false when Apex threw.

The advantage over `apex:actionFunction` is the one that mattered: no view state. A remoting call sends only its arguments and receives only its return value, where an action function round trips the entire serialised page state. On a complex page that is the difference between a snappy control and a two second pause.

The `escape` option defaults to true and HTML escapes the response. Turning it off because your markup looked wrong is how remoting pages get cross site scripting holes. Fix the rendering instead.

## Remote Objects

Remote Objects gave you create, read, update and delete from JavaScript with declarative markup and no Apex class.

```apex
<apex:remoteObjects>
    <apex:remoteObjectModel name="Account" fields="Id,Name,Industry">
        <apex:remoteObjectField name="AnnualRevenue" jsShorthand="revenue"/>
    </apex:remoteObjectModel>
</apex:remoteObjects>
```

Its selling point was that the generated calls respect sharing and field level security automatically, and do not consume API request allocation. Its limitation was that it only did simple record operations. Anything involving a join, a calculation or a rule went back to Apex, which is most things, so the feature never displaced remoting.

## What replaced them

Lightning Web Components cover the same ground with less ceremony.

- **Instead of Remote Objects,** the wire adapters in `lightning/uiRecordApi`: `getRecord`, `createRecord`, `updateRecord`, `deleteRecord`. Same no Apex promise, same automatic security, plus a cache that keeps components in sync when a record changes elsewhere on the page.

- **Instead of remoting,** an imperative or wired call to an `@AuraEnabled` Apex method. You get the same static method model, with `cacheable=true` available for read only calls.

- **For multi object reads,** the [GraphQL](https://trailassembly.com/salesforce-graphql-api/) wire adapter, which fetches related data in one request.

The practical differences favour LWC. `@AuraEnabled` methods do not have to be global. Errors come back as structured objects rather than a message string. The framework handles caching and refresh. And the component is reusable on a record page, a Flow screen, an app page and a community without being rewritten.

## Where Visualforce is still the right answer

Visualforce is supported and is not going away, and a handful of jobs still belong to it.

- **PDF generation.** `renderAs="pdf"` has no LWC equivalent. Quote documents and printable reports are still built this way.

- **Email templates** that need real logic in the markup.

- **Classic overrides and buttons** in orgs that have not migrated.

- **Pages that already exist and work.** Rewriting a functioning remoting page in LWC buys you nothing a user will notice.

A Visualforce page embedded in Lightning Experience runs in an iframe, which affects navigation, styling and anything that assumes it owns the window. If you are keeping a page, keep it in a place where that constraint is acceptable.

## Maintaining remoting code you inherited

Three checks are worth running on any remoting class you touch. Does it enforce sharing, given that `@RemoteAction` methods are static and the class declaration is the only place that is decided. Does it use `WITH USER_MODE` on its queries, since `WITH SECURITY_ENFORCED` is no longer supported. And is `escape` still on.

Remoting methods are also a public surface in a way a page controller is not, so treat every argument as untrusted input and bind or validate it accordingly.

## Frequently asked

**Do remoting calls count against the API limit?** No. They are page requests, not API requests, which is one reason high traffic Sites pages used them.

**Can a remoting method be `with sharing`?** The class can be, and that governs the method. Since the method is static and global, be explicit in the class declaration rather than relying on the default.

**Is Remote Objects deprecated?** Not formally removed, but it has had no meaningful investment for years. Do not start anything new with it.

**Should I migrate a working remoting page?** Only when you are changing it anyway, or when it needs to appear somewhere Visualforce cannot go. A rewrite with no user visible benefit is hard to justify and easy to get wrong.

---

Source: https://trailassembly.com/apex-visualforce-remoting/
Trail Assembly — independent Salesforce write-ups.
