A database-attach upgrade to Subscription Edition carries the content and leaves the code behind. Every solution the sites depend on is installed again on the new farm before the first content database is attached, and that reinstallation is the moment each piece of code is either carried across unexamined or decided on.

Two conclusions are tempting and both are wrong. The first is that farm solutions are obsolete and everything must become SharePoint Framework (SPFx) code. They are not: Microsoft documents them as supported on SharePoint Server. The second is that a solution which installs and attaches cleanly has been migrated. It has only been installed: whether it still works, whether it is secure, and whether it is still the right design are separate questions, answered component by component.

This analysis is for SharePoint Server 2016 and 2019 farms moving to Subscription Edition. Microsoft's documentation was read on 1 November 2026; no farm was accessed.

Three places code can run

Compared onFarm solutionSharePoint FrameworkExternal service
Where it runsOn the SharePoint servers, inside the farmIn the user's browserOn a server outside the farm
How it reaches SharePointThe server object model, with full trustClient APIs, as the signed-in userClient APIs (REST, CSOM), as its own identity or on a user's behalf
Whose rights it usesWhatever the code asks for, up to the farm'sThe user's, and only the user'sThe identity it is given
On Subscription EditionSupported on premisesSupported within the SPFx version the farm acceptsSupported where the APIs it calls are

Microsoft describes farm solutions as code that "is deployed to the SharePoint servers and makes calls to the SharePoint server object model", in assemblies that "always run with full trust", and states that farm solutions "are supported in SharePoint on-premises only" (build farm solutions, development models). SPFx is the client-side model, and which version a Subscription Edition farm accepts is a question with its own answer, set out in our article on developing for Subscription Edition. An external service is any application outside the farm that calls SharePoint's client APIs; it brings its own hosting, identity and availability with it.

The table's third row is the one that decides most cases. A farm solution can do anything the farm can. SPFx can do nothing the user cannot. An external service can do what its identity is granted. Moving code between them is never only a change of technology: it changes whose authority the code acts with.

What Microsoft says each is for

Microsoft's guidance on farm solutions is narrower than the way most farms used them: "SharePoint extensions that are primarily for use by end users should be developed as SharePoint Add-ins, not farm solutions. Farm solutions should be used for customizations of SharePoint administrative functions, such as custom timer jobs, custom Windows PowerShell cmdlets, and extensions of Central Administration." The same page notes that many older samples showed end-user extensions deployed as farm solutions, because that recommendation did not apply in SharePoint 2010.

That guidance predates SPFx and the retirement of add-ins in SharePoint Online. On SharePoint Server the add-in model is still available: Microsoft's retirement notice states that add-ins deployed through an on-premises app catalog "are not retired by this change", while acquiring add-ins from the public marketplace ended on 2 April 2026 for SharePoint Server too (add-in retirement). So on Subscription Edition all three hosts remain supported, and the choice is a design decision, not a forced migration.

Component by component

ComponentKeep as a farm solution whenMove whenCheck before deciding
Web partsThe behaviour needs server-side code or rights the user lacksIt only presents data the user can already read: SPFx, within the farm's versionWhether it elevates; what the user's own rights would show
Timer jobsThey administer the farm, which is what Microsoft says farm solutions are forThe work is a business process that can run outside: an external scheduler calling the client APIsWhich identity the job runs as, and what it touches outside SharePoint
Event receiversThey enforce a rule at the moment of change, inside the farmThe reaction can be asynchronous: an external serviceRemote event receivers without an app identifier: Microsoft's update notes say orphaned ones "will be blocked starting with the November 2026 Public Update"
Web services and handlersCallers are inside the farm's trust boundaryThey serve other systems: an external API with its own authorisationWhether callers are authenticated and authorised, and how
Feature receivers and provisioningProvisioning needs farm-level rightsProvisioning is a repeatable process: scripted, outside the farmWhich sites depend on the feature still being installed
Custom claims or membership providersSign-in depends on themThe identity design changes, for example to a trusted identity providerAnything that relied on the Claims to Windows Token Service, which Subscription Edition removed
web.config changesThe setting is still neededThe setting worked around something no longer presentEvery web application's file, because each is reapplied by hand
Sandboxed solutions with codeNot establishedA replacement is planned in any caseMicrosoft removed them from SharePoint Server 2019; the Subscription Edition pages read do not state their status

Sources for the table: build farm solutions, the August 2026 update notes, what is deprecated or removed from Subscription Edition, upgrade content databases and what is deprecated or removed from 2019, all read on 1 November 2026. The "keep" and "move" columns are our judgement, not Microsoft's.

A fourth answer belongs in every row: eliminate. A component nobody depends on any more is the cheapest one to migrate, and the usage evidence in the inventory, not the age of the code, is what shows it.

Identity decides more than the host

Moving code off the farm forces an identity decision that farm code could avoid. Inside the farm, code that needs more rights than its user calls SPSecurity.RunWithElevatedPrivileges. Outside it, Microsoft's guidance gives two options: an app-only permission, which "executes code based on the permissions granted to the SharePoint Add-in, not on behalf of another user", or a service account, whose name is then what the Modified By column shows (app-only and elevated privileges).

On premises, two details from the same guidance matter. The server-to-server (high-trust) option "only works in on-premises SharePoint environments", which makes app-only access available to an external service on Subscription Edition. And app-only access does not reach everything: the guidance lists search on premises, User Profile operations through CSOM and writes to the taxonomy service among the cases where a specific service account is needed instead.

Either way, the questions that applied to the elevated call apply to its replacement: who may ask for the operation, which permission they lack, which identity acts, how the request is authorised and what the audit trail records. Our analysis of privileged server-side code sets them out.

The order of the decisions

  1. Inventory every component, on the 2016 or 2019 farm, where the inventory commands still exist.
  2. Classify each one's dependencies: what it calls, which identity it uses, which features of SharePoint it relies on, and which of those Subscription Edition deprecated or removed.
  3. Decide each one: keep, adapt, replace or eliminate, with the reason.
  4. Rebuild what is kept or adapted against the target, and install it on a rehearsal farm.
  5. Test the content databases against it with Test-SPContentDatabase, then exercise each component, as Field Guide chapter 23 sets out.

A green Test-SPContentDatabase proves that the components the database references are installed. It does not run them. A kept component is accepted only when its own test has passed on the target build.

What this does not settle

  • Which SPFx version Subscription Edition accepts. Microsoft's pages disagree, and our development article records the disagreement rather than settling it.
  • Whether a given assembly works on Subscription Edition. Nothing on Microsoft's lists answers that for custom code; the rebuild and the test on the target build do.
  • The status of sandboxed solutions with code on Subscription Edition, which the Microsoft pages read do not state.

Where this fits

Tags#sharepoint#development#migration#spfx

Comments