Porting a small Connect app to Forge end to end: 10 things that broke, and what it took

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

  1. Everything server-side goes away. The panel calls Jira directly with requestJira from @forge/bridge, as the current user, the same thing AP.request did.
  2. UI Kit has no drag-and-drop. jQuery UI sortable became up/down buttons. If drag-and-drop is essential for you, that module needs Custom UI.
  3. UI Kit Textfield has no onKeyDown. To add an item on Enter, wrap the field in a Form and use onSubmit. I found this by reading the types in @atlaskit/forge-react-types, not in the docs.
  4. The issue-panel template scaffolds a resolver you may not need. If the frontend can call Jira itself, delete the resolver and the function module.
  5. REST v2 ‚Üí v3. The entity property endpoints are identical, so the payload didn’t change.
  6. Scopes are renamed and confirmed at install time. READ/WRITE became read:jira-work/write:jira-work. Use --confirm-scopes on the first install and forge install --upgrade when scopes change.
  7. forge create needs an interactive terminal to choose a Developer Space. In scripts, pass -s <developer-space-id> -y.
  8. Keep the generated app.id. If you rebuild manifest.yml from your own template, copy the app: block, or deploys go to a different app.
  9. Two bugs in the original weren’t carried over. Item text was rendered with innerHTML, and load errors silently showed an empty list.
  10. 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.

1 Like