With Connect end of support starting on 31 January 2027, I ported a small open-source Connect app to Forge from start to finish, to see what a real migration involves. The app is samid737/jira-checklist-plugin: one issue panel for checklists, running on Express, atlassian-connect-express, SQLite and jQuery UI.
The code and full write-up are here: GitHub - hermogenes-lopez/checklist-forge: Forge port of the open-source Jira checklist Connect app, with a Connect-to-Forge migration write-up · GitHub
Before and after
| Connect | Forge | |
|---|---|---|
| Hosting | Own Node/Express server | None |
| Auth | JWT per request (ACE) | Handled by the platform |
| Install lifecycle | /installed hook + tenant DB |
Not needed |
| UI | Handlebars + jQuery UI in an iframe | UI Kit |
| Storage | Issue entity property todos |
Same property, same JSON |
| Runtime deps | 12 | 3 |
| App code | 489 lines, 10 files | 141 lines, 1 file |
| Egress | Server + 3 CDNs | None (eligible for Runs on Atlassian) |
The most useful decision was keeping the entity property key and shape unchanged. A site can uninstall the Connect app, install the Forge one, and every existing checklist is still there. No data migration step is needed.
What broke
- Everything server-side goes away. The panel calls Jira directly with
requestJirafrom@forge/bridge, as the current user, the same thingAP.requestdid. - UI Kit has no drag-and-drop. jQuery UI
sortablebecame up/down buttons. If drag-and-drop is essential for you, that module needs Custom UI. - UI Kit
Textfieldhas noonKeyDown. To add an item on Enter, wrap the field in aFormand useonSubmit. I found this by reading the types in@atlaskit/forge-react-types, not in the docs. - The issue-panel template scaffolds a resolver you may not need. If the frontend can call Jira itself, delete the resolver and the
functionmodule. - REST v2 ‚Üí v3. The entity property endpoints are identical, so the payload didn’t change.
- Scopes are renamed and confirmed at install time.
READ/WRITEbecameread:jira-work/write:jira-work. Use--confirm-scopeson the first install andforge install --upgradewhen scopes change. forge createneeds an interactive terminal to choose a Developer Space. In scripts, pass-s <developer-space-id> -y.- Keep the generated
app.id. If you rebuildmanifest.ymlfrom your own template, copy theapp:block, or deploys go to a different app. - Two bugs in the original weren’t carried over. Item text was rendered with
innerHTML, and load errors silently showed an empty list. - The UI Kit bundle is cached by the browser. Hard-reload after every deploy, or you’ll be testing the previous version.
One thing worth checking on your own app
Under the 2026 revenue-share rules, an app that uses a Forge manifest but still contains Connect modules pays the Connect rate, which is 25% from 1 October 2026. The 0% Forge rate on the first $1M only applies once the app is Forge-only. While preparing this port I looked at paid Jira apps on the Marketplace. Quite a few are on a Forge manifest with a handful of Connect modules or scopes left over, and are still paying the Connect share. If you’ve “mostly” migrated, it’s worth checking versions/latest for your app.
Happy to answer questions about any of the above. I also help other vendors with Connect ‚Üí Forge migrations, so if you’re stuck on a specific module, post it here and I’ll take a look.