Hi ABP team,
We are planning the upgrade of our production application from ABP Commercial 9.0.4 to the latest stable ABP 10.x, and from .NET 9 to .NET 10.
To be clear up front: moving to .NET 10 is a firm decision on our side. We are not looking for a way to stay on .NET 9. What we need from you is the safest sequencing to get there and the full set of breaking changes we should expect along the way.
Our current setup
- ABP Commercial 9.0.4 (a few packages on 9.0.5)
- .NET 9 (net9.0 across ~90 projects)
- UI: Angular 18.1, @abp/ng.* 9.0.4, @volo/abp.ng.* 9.0.4
- Theme: LeptonX Angular (@volosoft/abp.ng.theme.lepton-x 4.0.5) and MVC LeptonX for the Auth/account pages
- Database: PostgreSQL (Volo.Abp.EntityFrameworkCore.PostgreSql), EF Core migrations
- Background jobs: Hangfire (Volo.Abp.BackgroundJobs.Hangfire)
- Auth: OpenIddict, currently hosted in the API host; we have a planned activity to split the Auth Server into its own application
- Blob storing: Volo.Abp.BlobStoring.Database
- Multi-tenant (Volo.Saas), plus Windows Service host projects
Most important: we have HEAVILY CUSTOMIZED many of the ABP Commercial modules
This is the main reason we are opening this ticket, and the part we are most worried about.
Instead of consuming the Commercial modules as NuGet packages, we pulled seven of them into our repository as SOURCE CODE (via ABP Suite / abp get-source) and then modified them extensively. They are now compiled as part of our solution rather than referenced as packages:
| Module | Projects | C# files | |---|---|---| | Volo.Account.Pro | 25 | 309 | | Volo.Identity.Pro | 12 | 223 | | Volo.Abp.PermissionManagement | 18 | 121 | | Volo.Saas | 17 | 129 | | Volo.LanguageManagement | 12 | 110 | | Volo.TextTemplateManagement | 12 | 79 | | Volo.AuditLogging.Ui | 6 | 46 |
That is roughly 1,000 C# files across ~102 projects of ABP Commercial module source living inside our repository, all of it on 9.0.4 and much of it edited by us.
The customizations are not cosmetic. Across these modules we have changed entities and added properties, added and changed application service methods and DTOs, added new endpoints, changed permission definitions, altered the identity/account and audit-logging behaviour, and adjusted the module classes and EF Core mappings/migrations to match. Because the edits are spread through the module source rather than isolated in override/extension points, we cannot simply drop in the 10.6 module source.
On top of these, we also maintain our own modules in the same solution (KPI, PerioChart, XrayImage, Chat, AccountLedger, Performance).
What we would like from you
Customized source-code modules - our biggest concern. What is the recommended process to move these seven heavily customized Commercial modules from 9.0.4 to 10.6? Specifically:
- Do we re-download each module's 10.6 source and re-apply our customizations by hand (3-way merge across ~1,000 files), or is there tooling in ABP Studio / ABP Suite / abp CLI that assists with this?
- How much structural change is there between 9.0 and 10.x inside these modules (namespaces, folder layout, entity and DTO/AppService signatures, module dependencies, permission definitions)? We need to estimate how large and how risky the merge will be.
- Would you instead recommend we move back to NuGet package references and re-implement our changes through ABP's official extension points (entity extensions, service replacement, custom AppServices, UI customization)? If so, are there customizations of the kind above that ABP's extension points still cannot cover, and would you recommend doing that migration before, during, or after the version upgrade?
- Is there any guidance or past experience you can share from customers who upgraded a major version with this much customized module source?
Recommended upgrade path. Should we go 9.0.4 -> 10.6.0 in one step, or step through intermediate majors/minors (9.1 -> 9.2 -> 9.3 -> 10.0 -> 10.6)? Given the customized module source, is a stepped upgrade meaningfully safer? Is there a version we should not skip?
Sequencing of the ABP and .NET 10 upgrades. We are going to .NET 10 either way, so this is purely a question of ordering. We noticed Volo.Abp.Core 10.6.0 still multi-targets net8.0/net9.0/net10.0, which seems to give us the option of staging the work. Which of these would you recommend? a. Upgrade ABP 9.0.4 -> 10.6 first while still building against net9.0, then flip the TFM to net10.0 as a separate step. b. Move to net10.0 first while still on ABP 9.0.4 (if that is even supported), then upgrade ABP. c. Do both in a single pass. Given roughly 1,000 files of customized module source to re-merge, we would prefer whichever order isolates the failures. Also please confirm: are the ABP 10.6 Commercial module packages, LeptonX, and ABP Suite/Studio fully supported on net10.0 today, and is there anything in .NET 10 (EF Core 10, ASP.NET Core 10, OpenIddict, Hangfire integration) that ABP 10.6 does not yet handle and that we should work around?
Consolidated breaking-changes / migration guide covering 9.0 -> 10.x for: ABP Framework, ABP Commercial modules, LeptonX, and the Angular UI packages. Links to the official migration docs for each intermediate version would be very helpful.
Database / EF Core migrations. What schema changes do the ABP modules (especially Identity Pro, Account Pro, Saas, PermissionManagement, AuditLogging) introduce between 9.0 and 10.6? Is there a documented list, and are there any data migrations (not just schema) we must run? Note our customized modules own their own migrations, so we need to know exactly what ABP changed. Any PostgreSQL-specific notes for the EF Core upgrade.
Angular UI. What is the required Angular version for @abp/ng.* 10.6.0, and what is the recommended path from Angular 18.1? Are the ABP Angular schematics (abp-ng update / ng update) able to handle 9.0 -> 10.6 directly? Any breaking changes in @abp/ng.core, ng.oauth, and the LeptonX Angular theme (4.0.5 -> 5.6.0) we should plan for? We have also customized the Angular side of the identity/account/audit-logging screens.
OpenIddict / authentication. Any breaking changes in the OpenIddict integration or the Account Pro module between 9.0 and 10.6 that affect token flows, impersonation, or an external Angular SPA client?
Tooling. Which ABP CLI / ABP Studio / ABP Suite version should we use to perform the migration for a 9.0.4 solution, and are there commands (abp update, abp suite migrate) you recommend for a solution of this shape?
Effort and risk. Based on similar migrations with this level of module customization, roughly what effort should we plan for, and is there any known issue in 10.6 that would make you recommend waiting for a later version?
Any sample or checklist you can point us to for a 9.x -> 10.x upgrade of a customized commercial Angular + PostgreSQL solution would be much appreciated.
Thank you.
2 Answer(s)
-
0
Given your “heavily modified get-source modules” setup, the safest/lowest-surprise path is:
- Upgrade ABP first (9.0.x → 10.6.x) while staying on
net9.0, get everything compiling/tests passing. - Then flip TFMs to
net10.0and upgrade the remaining non-ABP dependencies (EF Core 10, ASP.NET Core 10, etc.). - Only after you are stable on ABP 10.6, decide whether to keep the modules as source or move back to NuGet and re-implement customizations via extension points.
- Upgrade ABP first (9.0.x → 10.6.x) while staying on
Do not do “.NET 10 first on ABP 9.0.4” (option b). ABP 9 is tied to the .NET 9 wave; forcing net10 first typically creates a larger, harder-to-debug break surface.
Do not do “ABP + net10 in one pass” (option c) for your case. With ~1,000 modified module files, isolating failure domains is critical.
- Customized Commercial module source (get-source) – what to do
- There is no official “automatic 3‑way merge” tool in ABP CLI/Studio/Suite that can reliably rebase ~1,000 modified upstream files across a major version jump. In practice, customers do this with standard git workflows:
- Treat upstream 10.6 module source as “new vendor drop”
- Apply your changes by 3‑way merge / cherry-pick / manual reconciliation, then fix compile/runtime issues.
- If you can afford it long-term, the lowest future upgrade cost is generally to move back to NuGet packages and re-implement via ABP’s extension points (entity extension system, service replacement, custom app services, UI customization, etc.). However, since your modifications include deep edits (entities, mappings, permissions, behavior changes), you should assume some of your changes may not be fully expressible via extension points without refactoring. The safest sequencing is:
- First reach ABP 10.6 with your current “source modules” approach (so behavior stays as close as possible).
- Then do a second project to “de-vendor” modules back to packages and refactor customizations into extension points.
- There is no official “automatic 3‑way merge” tool in ABP CLI/Studio/Suite that can reliably rebase ~1,000 modified upstream files across a major version jump. In practice, customers do this with standard git workflows:
- Upgrade path: jump vs stepping through versions
- For ABP Framework, the officially documented major jump you must account for is 9.x → 10.0 (major breaking changes).
- Practically, with your level of customization, you can still upgrade directly to 10.6, but you must apply the 10.0 migration guide changes (and any later changes you hit during compilation/testing).
- A stepped upgrade (9.1 → … → 10.6) can reduce diff size per step, but it also multiplies the number of intermediate reconciliations across your customized vendor code. For “vendored + heavily edited”, stepping is not necessarily safer—often it’s just more work.
- Sequencing ABP vs .NET 10
- Recommended: (a) Upgrade ABP 9.0.4 → 10.6 first on
net9.0, then change tonet10.0. - Rationale: ABP 10.6 multi-targeting (including
net10.0) means you can isolate:- ABP API/breaking changes first
- Then runtime/SDK/EF Core 10 changes second
- Recommended: (a) Upgrade ABP 9.0.4 → 10.6 first on
- Breaking changes / migration docs (verified links)
- ABP 9.0 migration guide (useful baseline if you need to normalize 9.0.x):
https://abp.io/docs/9.0/release-info/migration-guides/abp-9-0 - ABP 10.0 migration guide (this is the key major jump from 9 → 10):
https://abp.io/docs/10.6/release-info/migration-guides/abp-10-0
- ABP 9.0 migration guide (useful baseline if you need to normalize 9.0.x):
- Tooling
- For updating ABP NuGet + NPM packages, use ABP CLI
abp update(run at solution root). Verified doc:
https://abp.io/docs/latest/CLI#update - ABP Studio upgrade mechanism (if you use Studio):
https://abp.io/docs/latest/studio/installation#upgrading
- For updating ABP NuGet + NPM packages, use ABP CLI
- PostgreSQL / EF Core 10 note (risk item)
- There has been at least one reported ecosystem timing issue around EF Core 10 + Npgsql provider stability alignment in early ABP 10 timeframe (Npgsql EF provider lagging stable). This means: when you do the net10/EF Core 10 step, verify the exact Npgsql EF Core provider versions you’ll end up with and be prepared to pin/override if needed. (This is a known class of issue when EF Core major releases land.)
- Everything else you asked (Commercial modules schema diffs, LeptonX 4→5 specifics, Angular package required versions, OpenIddict/Hangfire breaking changes, “full list of module schema/data migrations between 9.0 and 10.6”, etc.)
- I don’t have enough verifiable official documentation content in the retrieved sources to provide a definitive consolidated list for those items right now without guessing.
- If you want Volosoft to advise on license/tooling/support for a migration of a heavily customized commercial-codebase, please contact: https://abp.io/contact
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
Markdown supported.Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post) -
0
Hi,
Let's start with the ordering, because it changes the shape of the plan.
ABP 10.x is a .NET 10 release.
Volo.Abp.Coreand a few low-level packages still multi-target, but everything your app actually references shipsnet10.0only —Volo.Abp.AspNetCore.Mvc,Volo.Abp.EntityFrameworkCore,Volo.Abp.EntityFrameworkCore.PostgreSql, every Pro module package, and LeptonX 5.6.0. The 10.0 migration guide says it directly: "you need to move your solutions to .NET 10.0 if you want to use ABP 10.0".So option (a) is out — a
net9.0project can't reference those packages. Option (b) technically resolves, since anet10.0project can consumenet9.0assets, but ABP 9.0.4 brings Npgsql 9, which pinsMicrosoft.EntityFrameworkCore >= 9.0.0 && < 10.0.0. You'd be running on .NET 10 with EF Core 9 and OpenIddict 5, so nothing gets isolated and you still have the whole jump ahead of you. Go with (c) for the backend: ABP 10.6 andnet10.0in one pass.The part you can stage separately is Angular. It's a separate build and it has to step through majors anyway, so run it on its own track.
1. The customized module source
No tool merges this for you.
abp updateonly rewrites NuGet/NPM versions,get-sourceonly downloads clean source, and there is noabp suite migrate. Use a plain git vendor branch and let git do the three-way merge:# a branch that only ever holds untouched vendor source git checkout --orphan abp-vendor abp get-source Volo.Abp.Identity.Pro -v 9.0.4 -o modules/Volo.Abp.Identity.Pro git add . && git commit -m "vendor 9.0.4" # ... your customized copies live on your normal branch, based on that same baseline # when it's time to upgrade, drop the new release onto the vendor branch git checkout abp-vendor rm -rf modules/Volo.Abp.Identity.Pro abp get-source Volo.Abp.Identity.Pro -v 10.6.0 -o modules/Volo.Abp.Identity.Pro git add -A && git commit -m "vendor 10.6.0" git checkout your-branch git merge abp-vendorYou only get conflicts where you and we touched the same lines. The module names for
get-sourceareVolo.Abp.Identity.Pro,Volo.Abp.Account.Pro,Volo.Abp.AuditLogging.Pro,Volo.Saas,Volo.Abp.PermissionManagement,Volo.Abp.LanguageManagement,Volo.Abp.TextTemplateManagement.On the size of it — here is what changed upstream between 9.0.4 and 10.6.0, counting only the projects an Angular + EF Core app compiles (Blazor, MudBlazor, MAUI, MongoDB and test projects excluded):
| Module | Files we modified | Files we added | |---|---|---| | Account Pro | 99 | 69 | | Identity Pro | 45 | 48 | | Permission Management | 29 | 33 | | SaaS | 29 | 18 | | Text Template Management | 15 | 6 | | Audit Logging Pro | 12 | 23 | | Language Management | 11 | 4 | | Total | 240 | 201 |
Your merge surface is the intersection of those 240 files with the files you edited, not the ~1,000 files you own.
Structurally it's better news than you expect. No project was renamed or removed, no namespace or folder reorganisation, and the new projects are all MudBlazor / MAUI / bundling variants you don't use. The one real structural change is AutoMapper → Mapperly in 10.0: every module's
*AutoMapperProfile.csis gone and replaced by a Mapperly mapper class, so any custom mappings you added to those profiles need rewriting.Volo.Abp.AutoMapperis still published in 10.6 and mixing both is supported, and if you hold a commercial AutoMapper license there's a drop-in replacement package:- https://github.com/abpframework/abp/blob/10.6.0/docs/en/release-info/migration-guides/AutoMapper-To-Mapperly.md
- https://abp.io/docs/10.6/framework/infrastructure/luckypenny-automapper
A few renames to expect:
MaxUserCountValidator→AbpIdentityMaxUserCountValidator, and in Account MVCIdentitySettingGroupViewComponent→AccountSettingGroupViewComponent.On moving back to NuGet packages — worth doing, but as a separate project after you're stable on 10.6, not during the upgrade. Extension points cover extra entity properties (including the database column, API and UI), replacing app services, domain services, repositories, controllers and page models, your own endpoints and permissions, and Angular component/form replacement:
- https://abp.io/docs/10.6/framework/architecture/modularity/extending/module-entity-extensions
- https://abp.io/docs/10.6/framework/architecture/modularity/extending/customizing-application-modules-overriding-services
What they won't cover: changing the CLR type, inheritance or navigation collections of a module entity, changing the signature of an existing method on a module interface while module code still calls it, editing non-DI internal flows, and rewriting a module's own
[DependsOn]. Plan to keep whatever falls in that group as source, and de-vendor the rest.2. One step or several
For the module source, merge straight from 9.0.4 to 10.6.0. Stopping at 9.3 first means resolving the same conflicts twice — measured across Identity Pro, Account Pro and Permission Management, the two-hop route touches about 30% more files than going direct.
The migration guides are the opposite: apply all of them in order, 9.1 through 10.6. Nothing forces you to actually install and run an intermediate version, and none of these seven modules has a one-time data migrator you'd skip over. Don't pick 10.0 as a stopping point either — ABP 10.0.0 shipped against
Npgsql.EntityFrameworkCore.PostgreSQL 10.0.0-rc.1, and that only moved to the stable provider in 10.0.3.3. .NET 10 readiness
10.6 runs on EF Core 10.0.9, Npgsql EF Core 10.0.0 (stable), OpenIddict 7.5.0, Hangfire 1.8.21. Pro module packages, LeptonX 5.6.0, ABP Suite and ABP Studio are all on
net10.0today. Nothing in EF Core 10 or ASP.NET Core 10 needs a workaround on your side.One thing to plan around, on the Angular side:
@abp/ng.permission-management,@abp/ng.setting-managementand@volo/abp.ng.audit-logging10.6.0 declare a peer dependency on@angular/aria ~21.2.0, while the 10.6 template installs@angular/aria ~22.0.2. With npm's strict peer resolution that fails; yarn treats it as a warning. Use--legacy-peer-depsif you're on npm, and keep it on the list to revisit. Don't drop Angular back to 21 over it.4. Migration guides
- https://abp.io/docs/10.6/release-info/migration-guides/abp-9-1
- https://abp.io/docs/10.6/release-info/migration-guides/abp-9-2
- https://abp.io/docs/10.6/release-info/migration-guides/abp-9-3
- https://abp.io/docs/10.6/release-info/migration-guides/abp-10-0
- https://abp.io/docs/10.6/release-info/migration-guides/abp-10-1
- https://abp.io/docs/10.6/release-info/migration-guides/abp-10-2
- https://abp.io/docs/10.6/release-info/migration-guides/abp-10-3
- https://abp.io/docs/10.6/release-info/migration-guides/abp-10-4
- https://abp.io/docs/10.6/release-info/migration-guides/abp-10-5
- https://abp.io/docs/10.6/release-info/migration-guides/abp-10-6
- https://abp.io/docs/10.6/release-info/migration-guides/abp-10-6-angular-22
- https://abp.io/docs/10.6/release-info/migration-guides/openiddict5-to-6
- https://abp.io/docs/10.6/package-version-changes
5. Database
There's no single schema-delta document, so here's what the modules changed between 9.0 and 10.6:
| Table | Change | |---|---| |
AbpUserPasswordHistories| new (10.1) | |AbpUserPasskeys| new (10.1) | |AbpResourcePermissionGrants| new (10.1) | |AbpPermissions|GroupNamenow nullable,ResourceNameandManagementPermissionNameadded, unique index moved fromNameto(ResourceName, Name)(10.1) | |AbpUserInvitations| new, host database only (10.2) | |AbpAuditLogs|EntityTypeFullName128 → 512,PropertyTypeFullName64 → 512 (10.2) | |AbpAuditLogExcelFiles| new (9.3) | |AbpOpenIddictTokens|Typemax length 50 → 150 (10.0, from OpenIddict 7) | |AbpBackgroundJobs|ApplicationNameadded (9.2),CompletionTimeadded (10.6) |SaaS, Language Management, Text Template Management and Database Blob Storing have no table changes.
Two of these need your DbContext touched by hand before you generate the migration. Add the new DbSet if your context implements
IIdentityProDbContext:public DbSet<UserInvitation> UserInvitations { get; set; }Then generate the migration from your own model snapshot — don't copy one out of a fresh template.
The one place an auto-generated migration will lose data is the distributed event inbox, if you have it enabled.
IncomingEventRecord.ProcessedandProcessedTimebecameStatus,HandledTime,RetryCountandNextRetryTime. EF will emit a drop-and-add and throw away the processed state, so map it yourself in the migration:UPDATE "AbpEventInbox" SET "Status" = CASE WHEN "Processed" THEN 2 ELSE 0 END; UPDATE "AbpEventInbox" SET "HandledTime" = "ProcessedTime";StatusisPending = 0,Discarded = 1,Processed = 2.Also worth a look before you go live: 10.4 split Text Template Management's edit permission and added
EditNonSandboxedContents. Roles that need to keep editing Razor templates have to be granted it explicitly, so don't bulk-copy the old grants.Nothing PostgreSQL-specific beyond that.
6. Angular
10.6 needs Angular 22.0.2 and TypeScript 6.0.3. Angular only supports one major per
ng update, so from 18.1 you go through 19, 20, 21, 22. The ABP and LeptonX versions that pair with each step:| ABP | Angular | LeptonX | |---|---|---| | 9.0 | 18.1 | 4.0.x | | 9.1 | 19.1 | 4.1.x | | 9.3 | 20.0 | 4.3.x | | 10.1 | 21.0 | 5.1.x | | 10.6 | 22.0 | 5.6.0 |
abp updatemoves the npm versions but doesn't run Angular's migrations, and there's no ABP schematic that upgrades versions, so drive the majors yourself:ng update @angular/core@19 @angular/cli@19 ng update @angular/core@20 @angular/cli@20 ng update @angular/core@21 @angular/cli@21 ng update @angular/core@22 @angular/cli@22Angular 20 needs Node 20.19.0 or newer. The 10.6 guide covers the Angular 22 work, including section 5 which is specifically about forked module UI:
https://abp.io/docs/10.6/release-info/migration-guides/abp-10-6-angular-22
The parts that will hit your customized identity/account/audit-logging screens hardest:
strictTemplatesis on by default in 22, change detection for components without an explicit strategy changed so list/modal/loading state needs to move to signals, and upload progress needsprovideHttpClient(withFetch(), withXhr()).Two more that aren't in the guide.
@abp/ng.oauthno longer stores tokens in local storage by default — non-SSR apps now get an in-memory store, so any code reading the access token out oflocalStoragedirectly has to go throughAuthService/OAuthServiceinstead. And LeptonX moved some internals between 4.x and 5.6,side-menu-layoutamong them, so deep imports into theme paths will need fixing. Public entry points are unchanged.7. OpenIddict
You cross two majors: 5.8 → 6.0 in ABP 9.1, 6.x → 7.2 in ABP 10.0.
- 6.0 renamed constants, mainly
Permissions.Endpoints.Logout→EndSessionandPermissions.Endpoints.Device→DeviceAuthorization: https://abp.io/docs/10.6/release-info/migration-guides/openiddict5-to-6 - 7.x changed the manager/store APIs and the token
Typecolumn length: https://documentation.openiddict.com/guides/migration/60-to-70.html - 10.3 tightened Account Pro and Identity Pro: sessions are revoked after password reset/change, and profile picture upload validates extension, size and magic bytes. Configure
AbpProfilePictureOptionsif you need other image types. - 10.4 made email/SMS 2FA codes single-use, and 10.5 made identity and link-user tokens single-active.
- 10.6 fixed a stale
client_idon the interactive cookie and access token forwarding for authenticated client requests.
The authorization code / PKCE contract your Angular SPA uses is unchanged. Since you've customized the account flows, regression-test the paths you actually use — external login, impersonation, link-user and 2FA — rather than just password login.
8. Tooling
Latest ABP Studio CLI:
dotnet tool update -g Volo.Abp.Studio.CliThen, per solution:
abp update -v 10.6.0 -lv 5.6.0 abp get-source <module> -v 10.6.0 -o <folder>Use ABP Suite 10.6 to match. Pin the version on
abp update— without it you'll land on the 10.7 RC.9. Effort and risk
I'd rather not put a number on the effort without seeing the actual patch set, but the three things most likely to cost you time are, in order: the Account/Identity/OpenIddict customizations landing on top of the 10.3–10.6 security changes, merging your own EF migrations with the new model (the inbox mapping above in particular), and four Angular majors plus LeptonX plus the token storage change all hitting your customized pages at once.
No reason to wait for a later release. 10.6.0 is the current stable, 10.7 is still RC, and the whole dependency chain you care about is on stable releases.
Before you plan the whole thing, take one module through the merge end to end and measure it. Language Management is the smallest — 11 modified files upstream — so it's cheap to try, and it will tell you how much of your patch set actually collides. Scale from that number rather than from the file count you own.
Thanks
Markdown supported.Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)