← Back to Self-host Jira

Migrate from Jira to OpenProject

Issue tracking / agile boards · full migration guide

Jira → OpenProject is a CSV-bridged migration. Jira has a clean issue export to CSV, OpenProject has a clean Work Packages CSV importer, and the meeting point is a column-mapping spreadsheet. The work packages, sprints, and statuses transfer; the part that hurts is attachments (CSV doesn't carry binary), inline comments (CSV flattens them), and any deeply customized Jira workflows (you rebuild these as OpenProject types). Treat this as a structured-data migration with a manual attachment + comment pass.

Prerequisites

  • Jira project admin (you need access to the Issues → Export menu).
  • A self-hosted OpenProject instance — see /jira/ for the 20-minute docker-compose recipe and ~$10/mo VPS sizing.
  • OpenProject Community Edition is fine; the CSV import is in the open-source build (Modules → Work Packages → Import).
  • A spreadsheet tool (Google Sheets, Excel, or LibreOffice) for the mapping pass between Jira and OpenProject column names.
  • If attachments matter: a list of issue keys with attachments and a script (or volunteer) to download + re-attach them on the OpenProject side.

Step 1 — Export from Jira

  1. Open the Jira issue search

    In Jira, navigate to Filters → Advanced issue search. Enter `project = MYPROJ ORDER BY created ASC` (replace MYPROJ with your project key). This forms the basis of the export filter. Confirm the result count matches your project's issue total.

  2. Export to CSV (all fields)

    Click the Export button (top right) → Export CSV (All fields). Jira generates the CSV synchronously for projects under ~10,000 issues; larger projects need to chunk by date range (`AND created >= '2024-01-01' AND created < '2025-01-01'`).

  3. Inspect the CSV columns

    Open the CSV. Jira emits 50-100+ columns; most are empty. The columns you need: Issue Key, Issue Type, Summary, Description, Status, Priority, Assignee, Reporter, Created, Updated, Resolution, Labels. Note custom field columns — these will need mapping decisions.

  4. Pull attachments separately if needed

    Attachments do not appear in the CSV. To bulk-download, use the Jira REST API: `curl -u user:token https://yourcompany.atlassian.net/rest/api/3/issue/MYPROJ-123` returns a JSON with `fields.attachment[].content` URLs. Loop over your issue keys and save the attachments organized by key.

Step 2 — Import into OpenProject

  1. Create the destination project in OpenProject

    In OpenProject as admin, create a new project for the imported issues. Configure the project's work package types (Task, Bug, Feature, Epic) to match what your Jira project used — at minimum the same set of names so the CSV maps cleanly.

  2. Map columns

    OpenProject's Work Packages → Import (CSV) accepts a column header like Subject, Type, Status, Priority, Assignee. In your Jira CSV, rename: Summary → Subject, Issue Type → Type, leave Status/Priority/Assignee as-is. Save as a new CSV before upload.

  3. Run the CSV import

    OpenProject → Modules → Work Packages → ⋯ menu → Import. Upload the mapped CSV. Preview shows the first 10 rows; check Type and Status mapped correctly. Click Import. For 1000 issues expect 2-3 minutes; the importer logs each created work package.

  4. Re-attach files manually or via API

    Attachments are the manual part. For each issue key with an attachment, find the corresponding work package in OpenProject (search by the original Jira key — preserve it as a label or in the description), then drag-drop the attachment file. For volume, use OpenProject's API: `POST /api/v3/work_packages/{id}/attachments` with multipart form-data.

  5. Rebuild boards and sprints

    Sprint history does not transfer cleanly via CSV. In OpenProject, create a Backlog → New Sprint for each Jira sprint and bulk-move work packages into it via the work package list. Active sprints can be created live; closed sprints are mostly archival.

Field / concept mapping

Jira OpenProject Notes
Jira Issue Key (MYPROJ-123) Custom field or Description prefix OpenProject uses its own ID. Preserve the original Jira key in a custom field or as a `[MYPROJ-123]` prefix in the Subject so old links can be cross-referenced.
Jira Issue Type OpenProject Type Bug → Bug, Story → Feature (or User Story), Epic → Epic, Task → Task. Configure these in OpenProject's project settings before import.
Jira Status OpenProject Status Default Jira workflow (Open, In Progress, Done) maps cleanly. Customized workflows need OpenProject's status set extended to match — do this in System Admin → Work package types → Statuses.
Jira Priority OpenProject Priority Lowest, Low, Medium, High, Highest map 1:1 if you keep OpenProject's default priority set.
Jira Assignee OpenProject Assignee Match by email. Pre-create OpenProject accounts with the same emails as Jira before import — unmatched assignees become 'Unassigned'.
Jira Comment OpenProject Activity comment Comments do not flow via CSV. Use the Jira REST API to fetch each issue's comments (`/rest/api/3/issue/{key}/comment`) and post them via OpenProject's `POST /api/v3/work_packages/{id}/activities`. Or accept the loss for closed issues.
Jira Attachment OpenProject Attachment Manual or API-driven; not in the CSV.
Jira Sprint OpenProject Version or Sprint (Backlog plugin) Open the Backlogs module in OpenProject for sprint-shaped versions. Recreate each Jira sprint as an OpenProject sprint and bulk-assign issues.
Jira Custom field OpenProject Custom field Create the matching custom fields in OpenProject before import. Custom field values do flow via CSV if the column header matches the OpenProject custom field name.
Jira Workflow transition Manual policy OpenProject does not enforce per-status transition rules out of the box. Document your workflow as a runbook.

Downtime estimate

Half a day to one full day for a 1000-issue project: 1 hour to export and clean the CSV, 30 minutes to run the import, 2-4 hours to script and run the attachment + comment backfill, 1-2 hours to rebuild boards and sprints. The Jira project can stay live read-only during this — only freeze writes during the final cutover hour to avoid losing comments mid-flight.

Common gotchas

  • Jira's CSV export silently truncates Description fields with embedded line breaks under some configurations. Spot-check your 5 longest issues post-import.
  • Comments are NOT in the CSV. Most teams discover this after the import. Plan the API-driven comment backfill upfront if comments matter.
  • Sub-tasks come over but the parent → child link via CSV depends on Parent Issue Key being mapped — easy to forget.
  • Jira's `Resolution` field has no exact OpenProject equivalent. Either use a custom field or merge into Status (e.g. Done + Resolution=Won't Fix becomes a 'Won't Fix' status).
  • Custom workflows that require specific transition order are unenforced post-import. Write the workflow as a team norm rather than relying on OpenProject to gate it.

Rollback plan

Jira retains everything during the export — the original project is unchanged. If OpenProject doesn't fit, point the team back to Jira and you've lost only the time spent. Keep the exported CSV and the attachment dump for 30 days as a portable artifact that can also feed Plane (which has a Jira API importer) or Redmine without going back to Jira.

Looking for setup time, monthly cost, and other alternatives? See Self-host Jira.