Migrate from legacy Projects to Applications

Practical guide for mixed legacy Projects / Applications rollout: navigation, Move to Applications, redirects, shared compute, operator references.

Written By Zoro

Last updated 3 days ago

dFlow migration: Projects → Applications

dFlow is moving from legacy Projects to Applications with explicit Environments and Services. During rollout, your organisation can be in a mixed state: new work under Applications, older rows still listed under the legacy hub, and migrated projects that no longer appear in that list but still affect bookmarks and URLs. This page does not simplify that reality: it explains what to expect and how to move safely.

Read Legacy Projects vs Applications under Core Concepts in the sidebar for the mental model, then return here for actions.

Who this is for

  • Developers and leads choosing when to move a project and how to train the team on the new navigation.
  • Operators on self-hosted dFlow who coordinate backups and Payload migrations with engineering (see Repository migration references below).

On dFlow Cloud, platform rollout and bulk migration timing are operated by dFlow; you still use the same Move to Applications flows and URLs described here.

What “mixed legacy / new” looks like in the product

SituationWhat you see
New workPrimary navigation favours Applications. Create new Applications (and Environments) instead of new legacy Projects unless you are explicitly blocked.
Unmigrated legacy ProjectThe project still appears under the legacy Projects hub with its services and settings as before.
Migrated legacy ProjectThe legacy project is removed from the default legacy list (it is soft-deleted on the server). Services now sit under an Application and Environment.
Bookmarks and shared linksOld /project/[id] dashboard URLs are intended to redirect to the corresponding Application (not to a specific service deep link). Expect to update team bookmarks that pointed at legacy service URLs.
Legacy hub accessThe main nav may not show a Projects (legacy) entry. To open the legacy project list once, use your org dashboard URL with the query parameter legacyProjects=true (for example /{your-org}/dashboard?legacyProjects=true). The app can remember that choice for about 12 hours via a cookie so you do not need the query on every visit; bookmark it if your team still relies on the list.

If navigation differs between teammates, check whether everyone is using the Applications sidebar versus the legacy Projects hub.

Path A: Manual migration (per legacy Project)

Use this for a single project, for careful review, or when shared compute makes automatic choices sensitive.

  1. Open the legacy Project in the dashboard.
  2. Start Move to Applications from the project menu or an in-app banner when shown.
  3. Complete the wizard: it creates or selects an Application, attaches or creates an Environment, and binds compute (Worker Node or managed compute) as required.
  4. When shared compute already backs an Environment in your tenant, the wizard may attach the migrated services to that existing Environment instead of creating a duplicate; this is intentional.
  5. After completion, the legacy project is migrated (migratedToEnvironment is set server-side), draft wizard state is cleared, and the legacy project is soft-deleted so it drops off the default legacy list.

Outcome: Services are scoped to an Environment; you manage them under Applications going forward.

Path B: Bulk migration (operators, self-hosted)

For self-hosted control planes, operators run Payload database migrations after a full database backup. A bulk migration moves eligible legacy Projects to Applications in line with the same rules as the manual path (including shared compute reuse so one compute binding does not spawn duplicate environments).

  • Operator-facing steps, filters (test tenant / test project ids), idempotency, and cleanup behaviour are documented in the repository at docs/projects-to-applications-rollout.md.
  • Do not treat bulk migration as reversible through a “down” migration: rollback is restore from backup if you need to undo.

dFlow Cloud: You do not run these commands yourself; the same migration logic applies when the platform rolls it out for your workspace.

After migration: redirects and “still legacy” data

  • Redirects from legacy project routes target the Application root. Deep links that depended on the old project/service path may not land on the same screen; plan to share Application → Environment → Service URLs after cutover.
  • On the server, migrated Services may still carry internal references to the old project id for a period. A follow-up migration normalises service ownership (project / compute / environment / scope) so the data model matches the Applications UI. Operators run this as part of pnpm payload migrate when 20260402_000000_normalize_service_ownership is deployed; details are in docs/normalize-service-ownership-migration.md. Some rows may be skipped for manual review. That is expected for edge cases, not a silent failure.

If something looks wrong after migration (missing service, wrong environment), use Troubleshooting overview under Troubleshooting in the sidebar and contact support with the Application and Environment names.

Repository migration references

These files live in the dFlow open-source repository (for example when you clone dflow-sh/cloud):

  • docs/projects-to-applications-rollout.md: backup, bulk migration, redirects, legacy hub query parameter, shared compute, verification.
  • docs/normalize-service-ownership-migration.md: follow-up service ownership cleanup after projects → applications.

They are operator/engineering references, not substitutes for this customer guide.

Related