How Jira’s Forge Plugin System Enables Fast, Secure, Server‑Driven Extensions
This article explores Jira's plugin ecosystem, detailing how the Forge platform lets developers create, integrate, and deploy extensions using CLI tools, UI kit or custom UI, with server‑driven rendering, sandboxed security, and a marketplace for distribution.
This article is a research and summary of Jira’s plugin system.
Plugins are a common component of software systems, allowing flexible, customizable, and extensible modules that can be added without modifying the core code. In SaaS, plugins provide functionality extension, customization, and integration, enhancing flexibility and fostering ecosystem growth.
Function extension: add new features to meet specific business needs.
Customization: tailor the application to user preferences and workflows.
Collaboration and integration: enable seamless data sharing across services.
Designing a plugin system must consider developers, users, and the host system, providing capabilities for development, integration, and a marketplace.
Plugin development: tools, templates, API docs, SDKs.
Plugin integration: simple yet powerful APIs for embedding.
Plugin marketplace: a store for publishing and distributing plugins.
Jira, an Atlassian project‑tracking tool, supports plugins via the Forge platform. Development begins with installing the CLI, logging in, and creating a project from a template.
CLI
Using Forge CLI, a simple "Hello World" plugin is built with the following steps: login, create, deploy, and install.
login – authenticate with an Atlassian API token create – generate a plugin project from a template deploy – build, compile, and deploy the code install – install the app on a site with required API permissions
Forge uses JSX syntax; an IssuePanel plugin with a counter is implemented as:
<code>import ForgeUI, { render, Fragment, Text, IssuePanel, Button, useState } from "@forge/ui";
const App = () => {
const [count, setCount] = useState(0);
return (
<Fragment>
<Text>{count}</Text>
<Button onClick={() => { setCount(count + 1); }} text="click" />
</Fragment>
);
};
export const run = render(
<IssuePanel>
<App />
</IssuePanel>
);
</code>The
manifest.ymldefines the plugin configuration:
<code>modules:
jira:issuePanel:
- key: hello-world-app-hello-world-panel
function: main
title: hello-world-app
icon: https://developer.atlassian.com/platform/forge/images/icons/issue-panel-icon.svg
function:
- key: main
handler: index.run
app:
id: ari:cloud:ecosystem::app/xxxxxx-xxxx-xxxx-xxx-xxxxxx
</code>After deployment, the plugin appears in Jira's Issue panel.
Unified Design
Forge offers two UI options:
UI kit – for simple scenarios, provides Atlassian‑styled components rendered server‑side.
Custom UI – for complex cases, uses static assets (HTML, CSS, JS) served in an iframe, giving developers full flexibility.
Plugin Rendering
Jira supports two rendering modes:
Inline Rendering
Plugins return JSON describing the UI hierarchy, which the host renders. Example JSON for the counter plugin is shown below.
<code>{
"type": "render",
"aux": {
"type": "View",
"children": [
{
"children": [
{
"type": "Text",
"props": { "text": "0" }
},
{
"type": "Button",
"props": { "text": "click", "onClick": { "componentKey": "Button.0.0", "prop": "onClick" } }
}
],
"type": "IssuePanel"
}
]
}
}
</code>This approach loads minimal static resources, offers better security (logic runs in a FaaS), and simplifies multi‑device adaptation.
Embedded Rendering
For complex UI, a custom UI is embedded via an iframe, which may have UX challenges like overlay issues but provides ample space for rich interfaces.
Data Communication
UI kit plugins can access context data with
useProductContext:
<code>import ForgeUI, { useProductContext, Text, Macro, render } from '@forge/ui';
const App = () => {
const context = useProductContext();
return <Text>All info about my context: {JSON.stringify(context)}</Text>;
};
export const run = render(<Macro app={<App />} />);
</code>Custom UI plugins retrieve context via
view.getContext():
<code>import { view } from '@forge/bridge';
const context = await view.getContext();
</code>Plugins can listen to events, e.g., issue changes:
<code>import { events } from '@forge/bridge';
events.on('JIRA_ISSUE_CHANGED', data => {
console.log('JIRA_ISSUE_CHANGED (Forge)', data);
});
</code>Security
Forge ensures security through sandboxed execution, data isolation, and authentication. UI kit runs declaratively on the server, while custom UI assets are served in a sandboxed iframe with a strict Content‑Security‑Policy.
Plugin Types
Common plugin types include:
action – menu actions that trigger dialogs.
panel – UI rendered in a side panel.
page – standalone pages.
trigger – scheduled tasks, product events, or HTTP requests.
Additional types: custom field, background script, etc.
Plugin Marketplace
The marketplace provides installation, uninstallation, and configuration of plugins, serving as a distribution channel.
Conclusion
This article summarizes research on Jira’s plugin system, covering development, integration, rendering modes, security, and marketplace considerations, offering insights for building extensible Atlassian applications.
KooFE Frontend Team
Follow the latest frontend updates
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.