Turn an open Jira issue into clean, portable Markdown—with its images and attachments.
No copy-and-paste marathon, Jira API token, or cloud conversion service. Open an issue in Safari, choose what belongs in the export, and download either one Markdown file or a self-contained ZIP archive.
Important
The project is independent and is not affiliated with, endorsed by, or sponsored by Atlassian. Jira is a trademark of Atlassian.
| Portable by default | Useful offline | Private by design |
|---|---|---|
| Produces readable Markdown and predictable relative paths. | Packages inline images and attachments next to the document. | Parses the open page locally—no Jira REST API or third-party backend. |
It is useful for engineering handoffs, incident archives, migrations, knowledge bases, audits, and keeping important context outside a single Jira instance.
- Selective export: description, comments, metadata, images, and attachments can be enabled independently.
- Per-file attachments: expand the attachment option and toggle individual files before creating the archive.
- Formatting preservation: headings, lists, task lists, tables, quotes, links, code, bold, italic, strikethrough, and useful inline styles.
- Offline resources: images and attachments are stored in a ZIP with relative Markdown links.
- Safe fallback: if a binary resource cannot be saved, its original link remains and the reason is written to
export-log.txt. - Finder handoff: click the underlined success message to reveal the exported file in Finder.
- Parse validation: the popup shows the issue key, type, status, resource counts, and readiness before export.
- Share-safe links: replace HTTP/HTTPS domains with
example.com, with locally saved exact-host and wildcard exceptions for links that should remain unchanged. - IP privacy: replace IPv4 and IPv6 values with documentation-safe addresses, with separate exact-address and wildcard exceptions.
- Jira-inspired UI: accessible light and dark themes with a remembered preference.
- No runtime dependencies: the parser, Markdown renderer, and ZIP writer are plain JavaScript shipped with the extension.
When local resources are selected, the extension creates a portable archive:
JIRA-123.zip
├── JIRA-123.md
├── assets/
│ ├── images/
│ │ ├── architecture.png
│ │ └── error-state.png
│ └── attachments/
│ └── requirements.pdf
└── export-log.txt # only when a resource could not be saved
If the selected sections do not contain downloadable resources, the result is a single JIRA-123.md file.
Download the ready-to-use universal macOS build from the latest GitHub release. No Xcode, Node.js, or build tools are required.
- Download
Jira-Markdown-Export-macOS.zipfrom the release assets—not the automatically generated Source code archive. - Extract the ZIP and move
Jira Markdown Export.appto Applications. - Open the application once.
- Open Safari → Settings → Extensions.
- Enable Jira Export — Markdown and allow access to your Jira website.
- Open an individual Jira issue and click the extension icon in Safari's toolbar.
Warning
Current release builds are ad-hoc signed and not notarized. If macOS blocks the first launch, try opening the app once, then go to System Settings → Privacy & Security, scroll to Security, and click Open Anyway. Only bypass the warning for an archive downloaded from this repository's Releases page.
- macOS 13 or later;
- Safari with Web Extension support;
- a current Xcode release;
- Node.js 20 or later for scripts and tests.
-
Clone the repository using GitHub's Code button, then enter the project directory:
cd jira-export-md-safari -
Generate or synchronize the Safari host project:
npm run build:safari
-
Open Jira Markdown Export.xcodeproj in Xcode.
-
Select the Jira Markdown Export macOS scheme. If Xcode requests it, choose your Personal Team under Signing & Capabilities.
-
Run the app.
-
Open Safari → Settings → Extensions, enable Jira Export — Markdown, and allow access to your Jira domain.
Now open an individual Jira issue and click the extension icon in Safari's toolbar.
Note
Building from source is an alternative for contributors and users who prefer to sign the application with their own Apple development team.
flowchart LR
A["Open Jira issue"] --> B["DOM parser"]
B --> C["Normalized issue model"]
C --> D["Markdown renderer"]
D --> E{"Local resources selected?"}
E -- No --> F["JIRA-123.md"]
E -- Yes --> G["ZIP writer"]
G --> H["Markdown + images + attachments"]
The content script reads the rendered issue page and builds a normalized local model. It never searches Jira, calls the Jira REST API, or sends exported content to a service.
For images, the extension first tries to read the already rendered element through Canvas. When Safari prevents that, it may retrieve only the resource URL already present in the open page, using the current browser session. When offline, text still exports; unavailable binary resources remain as links.
| Permission | Why it is needed |
|---|---|
activeTab |
Inspects and exports only the tab where the user opens the popup. |
nativeMessaging |
Asks the bundled macOS extension to reveal a completed export in Finder when the user clicks its filename. |
storage |
Remembers export options, anonymization exceptions, and the light/dark theme preference locally. |
http://*/*, https://*/* |
Supports Jira Cloud and self-hosted Jira domains whose URLs cannot be known in advance. |
The extension contains:
- no analytics or telemetry;
- no advertising or tracking SDKs;
- no cloud synchronization;
- no Jira API client;
- no runtime CDN or third-party JavaScript;
- no external backend.
The Finder action searches only the local Downloads folder for the exported filename. If Safari uses a custom download location or the file is not yet available, the extension opens Downloads without selecting a file. No filename or filesystem information leaves the Mac.
Enable Anonymize all links before export to replace the domain in every HTTP/HTTPS address with https://example.com. This includes Jira, Figma, documentation, file storage, and other linked sites. Paths, query parameters, and anchors are preserved, while original domains are removed from Markdown, encoded URLs, fallback resource links, and export logs.
Expand that option to add exceptions for domains that should keep their original links. Rules support exact hosts such as jira.example.com and * wildcards such as jira.*.com or *.site.com. Empty values, incomplete domains, URLs, and invalid domain characters are rejected. Each valid rule can be enabled, disabled, or deleted, and stays in Safari's local extension storage.
Enable Anonymize IP addresses to replace IPv4 and IPv6 values in Markdown text, web links, fallback logs, and packaged resource names. IPv4 becomes the documentation address 192.0.2.1; IPv6 becomes 2001:db8::1. Expand the option to keep selected values unchanged with exact rules such as 10.20.30.40 or wildcard rules such as 10.20.*.* and 2001:db8::*. IP rules have the same validation, per-rule toggle, deletion, animation, and local persistence behavior as domain rules.
Anonymization intentionally preserves URL paths, query parameters, anchors, and the rest of the exported issue text. Review the completed export before sharing it if those values may also contain confidential information.
Please review SECURITY.md for the security model and private vulnerability reporting process.
The parser contains fallbacks for current Jira Cloud and classic Jira Server/Data Center layouts. Atlassian, marketplace apps, custom fields, and organization themes can change the DOM, so no DOM parser can promise universal compatibility.
If your layout is not recognized, open a sanitized bug report. Parser selectors live in extension/content/content.js, making instance-specific support straightforward to contribute without changing the architecture.
Run all fast checks:
npm run verifyOr run them separately:
npm run check
npm testPreview the popup without a Jira account:
python3 -m http.server 8000Open http://localhost:8000/extension/popup/popup.html?preview=1 and switch between the light and dark themes.
Build a universal arm64 + x86_64 verification archive:
npm run build:releaseThe result is written to build/artifacts/Jira-Markdown-Export-macOS.zip. It is ad-hoc signed and intended for verification, not notarized public distribution.
For the versioning and GitHub publication checklist, see Releasing.
.
├── extension/ # Source of truth for the Web Extension
│ ├── content/ # Jira parser, Markdown renderer, ZIP export
│ ├── popup/ # Popup UI and theme system
│ ├── shared/ # Shared export helpers
│ └── manifest.json
├── SafariApp/ # Native macOS host and Xcode project
├── scripts/ # Project synchronization and release build
├── tests/ # Node tests and sanitized fixtures
└── .github/ # CI and contribution templates
extension/ is the source of truth. Running npm run build:safari synchronizes it into the Xcode project while preserving schemes and local signing settings.
Every push and pull request runs:
- syntax checks and tests on supported Node.js versions;
- a clean universal Safari app build on a GitHub-hosted macOS runner;
- architecture and ad-hoc signature verification;
- upload of the zipped macOS build as a short-lived workflow artifact.
GitHub Actions dependencies are updated automatically through Dependabot.
Bug fixes for another Jira layout, better Markdown output, accessibility improvements, and focused tests are all welcome. Read CONTRIBUTING.md before opening a pull request, especially the rules about sanitizing Jira fixtures.
If the project saves you time, consider starring it—it helps other Safari and Jira users discover it.
- broader fixture coverage for Jira Cloud and Data Center layouts;
- richer custom-field rendering;
- configurable export filenames and folder templates;
- optional localization packs;
- Developer ID signing and notarized GitHub releases.
Released under the MIT License.