Course menuForge Kitchen

A hands-on course on Atlassian Forge

Build a Forge app for a restaurant kitchen, one step at a time.

Forge is Atlassian’s platform for apps that run inside Jira and Confluence, on Atlassian’s own cloud. In this course you build one app: a recipe card on every dish ticket in Level 1, then a back kitchen with an AI sous-chef in Level 2.

Start here
  1. 1 Understand how Forge works
  2. 2 Set up your laptop
  3. 3 Build Level 1, then Level 2
KIT-12Kitchen / Dish tickets

Pad thai

Recipe card

Pad Thai 4 servings

Ingredients

  • 8 oz rice noodles
  • 2 tbsp tamarind paste
  • 1 cup bean sprouts

Method

Soak the noodles, then stir-fry with the sauce…

An illustration of what Level 1 builds: the recipe comes from an outside supplier, the card is yours.

One diagram, used everywhere in the course. Scroll and it tells the story one step at a time. Switch between Technical and Kitchen to see how each part maps onto the restaurant: the boxes never move, only their names change.

How Forge fits together

How a Forge app works

Three places matter: your laptop, where you write code; the browser, where Jira shows your UI; and the Atlassian cloud, where your functions run.

In the kitchen: Three places: your home kitchen, where you write the playbook; front of house, where staff see the cards; and back of house, where the cooking happens.

Lives on your laptop · Home kitchen

Your code The playbook

The JavaScript in your app folder: the frontend that draws the UI and the functions that run in the cloud.

How your kitchen works, written down. Not to be confused with recipes, which come from the supplier.

Select any box in the diagram to see what it is.

  1. Three places. You write code on your laptop. People use your app in their browser, inside Jira. The code runs in the Atlassian cloud, next to Jira’s data. In this course they are the home kitchen, front of house and back of house.

  2. Your code and its manifest travel together. The app is a folder: JavaScript in src/ and a manifest.yml that says what the app adds to Jira and what it may do. The Forge CLI is the only thing that carries it into the cloud.

  3. Deploy. forge deploy uploads a new version. Atlassian hosts it: no servers, no containers, no databases to run yourself.

  4. Install. forge install puts the app on one site, once. From then on, every deploy reaches that site by itself. Use your own developer site, never your company’s.

  5. A click becomes a call. The app’s UI runs in the browser. When it needs something only the backend can do, it calls invoke() with a name, and a resolver function in the cloud answers.

  6. Reading Jira safely. The resolver reads the work item it is shown on, as the person viewing it. The manifest has to grant that permission, called a scope, or Jira says no.

  7. Secrets stay in the back. The key for the outside service comes from an encrypted variable, read only by backend code. It never appears in the code or reaches the browser.

  8. Calling outside Atlassian. Forge blocks calls to other hosts unless the manifest lists them. The course calls API Ninjas for recipes, so api.api-ninjas.com goes on the list.

  9. The answer comes back. The resolver returns the recipe, and UI Kit draws it on the work item. That round trip is all of Level 1, built one step at a time.

  10. Longer jobs wait their turn. Every function has a time limit. In Level 2, a page saves a job in storage, pushes a small event onto a queue and answers at once, so nobody waits.

  11. AI, hosted by Atlassian. A consumer function picks up the event later and asks Forge LLM to read meeting notes and list the dishes. The model runs inside Atlassian’s platform.

  12. Back into Jira and Confluence. The consumer creates a work item per dish, writes a Confluence page, and a Rovo agent can research the dishes. Each of these is a new box on the same diagram.

The building blocks

Every part of the story, explained once. Lessons link back here when they use one.

Runs in the Atlassian cloud · Back of house

Forge · the building

Forge is Atlassian’s platform for apps that extend Jira, Confluence and other Atlassian products. You write the code; Atlassian deploys it, runs it, scales it and keeps it close to the product’s data. You never run a server.

In the kitchen Atlassian runs the building: power, security and the doors. You run a kitchen inside it.

Atlassian docs: Forge overview (opens in a new tab)

Runs in the Atlassian cloud · Back of house

Forge app · your restaurant

One Forge app is one folder: code in src/, a manifest.yml, and a package.json. A single app can add several things to Jira and Confluence at once, which is how this course grows one app across both levels.

In the kitchen Your restaurant: the playbook, the licence and every station that follows them.

Lives on your laptop · Home kitchen

App code · the playbook

The JavaScript in your app folder. Some of it runs in the browser (the UI), and some runs in the Atlassian cloud (functions). Which is which is decided by the manifest, not by where the file sits.

In the kitchen How your kitchen works, written down. Not to be confused with recipes, which come from the supplier.

Declared in manifest.yml · The licence

manifest.yml · the licence

manifest.yml is the app’s description of itself. modules lists what it adds, resources lists the files it serves to the browser, and permissions lists what it may touch: product scopes and outside hosts. Forge checks every call against it.

In the kitchen The licence on the wall says which stations you run, which systems you may touch and which suppliers you may call.

Atlassian docs: Manifest reference (opens in a new tab)

Declared in manifest.yml · The licence

Module · a line on the licence

A module is one thing the app adds, such as jira:issuePanel, trigger or consumer. Each has a key that is unique in the manifest, and most point at a function or a resource.

In the kitchen Each line on the licence names one thing you are allowed to run.

Atlassian docs: Modules (opens in a new tab)

Runs in the Atlassian cloud · Back of house

Function · a station

A function is an entry point in your code that Forge runs in the cloud. The manifest names it with a key and a handler: index.handler means the export handler in src/index.js. Each run has a time limit.

In the kitchen A station in back of house with one cook and one job.

Atlassian docs: Function reference (opens in a new tab)

Runs in the browser · Front of house

invoke() · the runner

invoke('name', payload) comes from @forge/bridge. It lets UI code ask the backend for something by name and wait for the answer. The browser never reaches Jira or outside services directly; it asks a resolver.

In the kitchen The runner carries a request from front of house to the cook and brings the answer back.

Atlassian docs: Bridge API (opens in a new tab)

Runs in the Atlassian cloud · Back of house

Resolver · the cook

A resolver is a function that answers invoke() calls. In code, resolver.define('getDish', fn) registers a name, and resolver.getDefinitions() hands all of them to Forge. Forge also passes a context that says where the call came from.

In the kitchen The cook knows each dish by name, prepares it and sends it back with the runner.

Atlassian docs: Forge resolver (opens in a new tab)

Lives on your laptop · Home kitchen

Forge CLI · the delivery van

The forge command on your laptop. It creates apps from templates, deploys and installs them, runs a local tunnel, sets variables and reads logs. You need Node.js for it.

In the kitchen The only thing that carries your playbook from your home kitchen into the building.

Atlassian docs: Forge CLI reference (opens in a new tab)

Lives on your laptop · Home kitchen

Atlassian API token · the van’s permit

forge login asks for your Atlassian email and an API token, which you create in your Atlassian account settings. Treat the token like a password: never paste it into code, chats or screenshots.

In the kitchen The permit that lets your van through the building’s gate.

Lives on your laptop · Home kitchen

Deploy · deliver the playbook

forge deploy builds and uploads a new version of the app. It goes to the development environment unless you say otherwise. Sites that already have the app pick the new version up by themselves, unless it asks for new permissions.

In the kitchen The van drops the new playbook at the building. No location uses it until it is opened there.

Atlassian docs: forge deploy (opens in a new tab)

Lives on your laptop · Home kitchen

Install · open at a location

forge install adds a deployed app to one site and one product, such as Jira. You install once per site and product. A Level 2 app that also writes to Confluence is installed on Confluence too.

In the kitchen Opening your restaurant at one location. After that, every new playbook delivery reaches it.

Atlassian docs: forge install (opens in a new tab)

Runs in the Atlassian cloud · Back of house

Environment · a kitchen copy

Each app has separate environments: development by default, plus staging and production. Each has its own deployments, installations and variables, so experiments never touch the production copy.

In the kitchen Separate copies of your kitchen, so trying something new never touches the one that serves real customers.

Atlassian docs: Environments and versions (opens in a new tab)

Atlassian’s own products · House systems

Site · a location

An Atlassian cloud site is one address, such as your-name.atlassian.net, with its own Jira, Confluence, users and data. Apps are installed per site.

In the kitchen A location in the building where a restaurant can open.

Atlassian’s own products · House systems

Developer site · your test location

A free site of your own for building apps. Create one during setup. Building on your company’s site risks real data and needs admin rights you may not have.

In the kitchen A location nobody eats at, where you can burn things safely.

Atlassian docs: Provision a development site (opens in a new tab)

Runs in the Atlassian cloud · Back of house

Runtime limits · the kitchen timer

A function invoked from the UI or by a product event has a short time limit; a queue consumer can be given longer. That is why Level 2 answers the page first and does the slow work in a consumer. Atlassian lists every limit in its quotas page.

In the kitchen Every station works against a timer. Long jobs go to the back, where the timer is longer.

Atlassian docs: Quotas and limits (opens in a new tab)

Runs in the Atlassian cloud · Back of house

Forge SQL · the storeroom ledger

Besides the Key-Value Store this course uses, Forge offers a hosted SQL database per installation, for data you need to filter and join. You will not need it here, but it sits in the same back of house.

In the kitchen A ledger with columns, for stock you need to count and cross-check. Not needed for this restaurant.

Atlassian docs: Storage reference (opens in a new tab)

Lives on your laptop · Home kitchen

Forge MCP server · the rulebook on call

Atlassian runs an MCP server that gives AI coding tools current Forge documentation, templates and guides. Connecting it to your editor is optional; the setup shows how.

In the kitchen Someone who knows the building’s rulebook by heart, on call while you write your playbook.

Atlassian docs: Forge MCP (opens in a new tab)

How the files connect

A new app from the template has four small files. Step through the clues to see how a click in Jira finds the right function. This is the template you start Level 1 with.

How invoke() finds its function

  1. Clue 1 of 6: It starts with a name

    The panel calls invoke('getText', …). It does not know where the code runs; it only knows the name of what it wants.

    The card sends the runner asking for “getText”, without knowing which cook makes it.

  2. Clue 2 of 6: The manifest declares a panel

    Under modules, jira:issuePanel adds a panel to every work item. Its key is its name inside the app; title is what Jira shows.

    The licence has a line that says your restaurant clips a card to every dish ticket.

  3. Clue 3 of 6: resource: main points at the UI file

    resource: main refers to the resources list, where main maps to src/frontend/index.jsx. That file draws the panel.

    The licence says which card design to use.

  4. Clue 4 of 6: resolver → function names the code that answers

    When this panel calls invoke(), Forge runs the function whose key is resolver, declared under function.

    Runners from this card always go to the station called “resolver”.

  5. Clue 5 of 6: handler: index.handler is a file and an export

    Read it as “in src/index.js, use the export handler”: the file comes before the dot, the export after it.

    An address: the street is the file, the door is the export.

  6. Clue 6 of 6: getDefinitions() finds the right function

    resolver.getDefinitions() bundles every resolver.define(…). Forge reads the name from invoke(), runs the match, and returns its result to .then(setData).

    The cook reads the request, finds the method with that name in the playbook, and sends the result back.

src/frontend/index.jsxThe panel’s UIThe recipe card
import React, { useEffect, useState } from 'react';import ForgeReconciler, { Text } from '@forge/react';import { invoke } from '@forge/bridge'; const App = () => {  const [data, setData] = useState(null);  useEffect(() => {Highlighted:     invoke('getText', { example: 'my-invoke-variable' }).then(setData);  }, []);  return (    <>      <Text>Hello world!</Text>      <Text>{data ? data : 'Loading...'}</Text>    </>  );}; ForgeReconciler.render(  <React.StrictMode>    <App />  </React.StrictMode>);
manifest.ymlThe manifestThe licence
modules:  jira:issuePanel:    - key: mise-en-place-hello-world-issue-panel      resource: main      resolver:        function: resolver      render: native      title: Mise en place      icon: https://developer.atlassian.com/platform/forge/images/icons/issue-panel-icon.svg  function:    - key: resolver      handler: index.handlerresources:  - key: main    path: src/frontend/index.jsxapp:  runtime:    name: nodejs24.x    memoryMB: 256    architecture: arm64  id: ari:cloud:ecosystem::app/<your-app-id>
src/index.jsEntry pointThe kitchen door
export { handler } from './resolvers';
src/resolvers/index.jsThe resolverThe cook
import Resolver from '@forge/resolver'; const resolver = new Resolver(); resolver.define('getText', (req) => {  console.log(req);  return 'Hello, world!';}); export const handler = resolver.getDefinitions();

Set up your laptop

General setup only: what every level needs. One step at a time; tick each one when it works. Anything a level needs on top of this, such as the supplier’s key, is in that level’s first lesson.

Step 1: Check Node.js

The Forge CLI and your app’s build run on Node.js. Use an LTS release: Node 22 or 24. The example app runs on Forge’s nodejs24.x runtime, so Node 24 matches best.

RunTerminal
node --version
npm --version

If Node is missing or older, install it from nodejs.org (opens in a new tab), or with a version manager such as nvm (opens in a new tab) so you never need sudo.

Stuck? npm reports permission errors when installing the CLI · “Unable to get local issuer certificate”

Step 2: Install the Forge CLI

Install the CLI globally, then check it answers:

RunTerminal
npm install -g @forge/cli@latest
forge --version

Run the same install again whenever the CLI tells you it is out of date.

Stuck? npm reports permission errors when installing the CLI · Installing the CLI fails with “spawn ts-node ENOENT” · The CLI says it is out of date, or forge tunnel mentions ngrok · “Unable to get local issuer certificate”

Step 3: Log in with an API token

Create an API token in your Atlassian account at id.atlassian.com/manage-profile/security/api-tokens (opens in a new tab). Then log in; the CLI asks for your email and the token:

RunTerminal
forge login
forge whoami

The token acts as you. Keep it out of code, chats and screenshots, and revoke it when the course is over.

Step 4: Get a developer site

Apps are installed on a site. Use a free site of your own, never your company’s real Jira. The CLI can create a free demo site for development and testing, or show the one you already have:

RunTerminal
forge site provision

It prints the site’s address, its status and when it expires. A developer site you already created from Atlassian’s developer pages works just as well.

Open the site in your browser and check Jira loads. Level 2 also uses Confluence and Rovo on the same site; its first lesson checks them.

Stuck? `forge site provision` is not available or fails

Step 5: Optional: give your AI coding tool the Forge rulebook

If you use an AI coding tool, connect Atlassian’s Forge MCP server so it reads current Forge documentation instead of guessing. Most tools take an MCP entry like this:

CodeJSON
{
  "mcpServers": {
    "forge": { "type": "http", "url": "https://mcp.atlassian.com/v1/forge/mcp" }
  }
}

Atlassian also publishes Forge skills for several editors, which bring the same server with them. In Claude Code, run /plugin install forge-skills@atlassian-forge-skills. The Forge MCP page (opens in a new tab) lists the other editors.

This step is optional: the course does not depend on it.

Then build it

Type at least two letters.