The Forge app runtime includes a set of APIs that provide additional functionality to the Forge platform. You can use these APIs to interact with REST endpoints and to store data.
This runtime runs standard Node.js 18 and Node.js 20 versions; we also intend to support newer versions as they become available. As such, you can import any built-in, local, or third-party Node modules into your app. This provides compatibility with all Node libraries and NPM packages, allowing you to leverage the entire JavaScript developer ecosystem.
For details about the legacy sandbox runtime (including instructions for migration), see Upgrading from legacy runtime.
The new native Node.js runtime requires the latest version of all Forge packages. Install updates for the packages your app uses, from the command line. For example:
1 2npm install -g @forge/cli@latest npm install @forge/api@latest
Repeat the npm install
command for any other Forge packages your app uses.
The runtime
section of the manifest.yml
file features a name
property that lets you specify what runtime to use. To specify the native Node.js runtime, set name
to nodejs18.x
:
1 2app: runtime: name: nodejs18.x | nodejs20.x
Adding the runtime.name
property to the manifest file will not trigger a major upgrade. As such, deploying this change alone to production will automatically install it on all sites.
The Forge runtime allows your app to run directly on a secure VM environment. Your app will be provided with 512MB of memory per invocation. For a complete list of resource limits provided per app invocation, refer to Platform quotas and limits.
At invocation time, Forge calls a context function. Each module receives different request parameters based on the module type.
You can also explicitly request a Forge function’s context details (for example, the environments and versions an app is executing in). See getAppContext for more information.
Within the Forge runtime, it is your responsibility to ensure customer data does not persist across app invocations. Our shared responsibility model lays out these responsibilities.
To comply with these responsibilities, review your app code to ensure that:
Your app must not persist customer data or sensitive content in global state, in memory or on disk, between subsequent invocations.
Your app must not copy customer data or sensitive content from one installation to another, unless it has been explicitly permitted by the customer.
Your app must not persist tenant-related data in global variables. This includes registering callbacks to be executed later if they are stored in a global queue.
In your app code, ensure callbacks only uses variables from the current invocation, and doesn't refer to global variables that might be modified by the next invocation
When calling Atlassian APIs like storage
, requestJira
, requestConfluence
, the Forge runtime
automatically provides the context of the current request. This ensures that operations are executed
against the correct tenant.
If you encounter an error with message Forge runtime metadata not found. Visit https://go.atlassian.com/nodejs-runtime for more information
,
that's because the runtime context is lost in a rare situation. You can resolve the issue by following the below steps:
bindInvocationContext
API to wrap the call.Code example:
1 2import { bindInvocationContext, storage } from '@forge/api' import { SomeClient } from 'some-library'; const handler = async () => { const client = new SomeClient(); // If calling within a particular event listener produces "Error: Forge runtime not found...." errors, for example: // client.on('data', async () => { // await storage.set('foo', 'bar'); // }); // Verify tenant isolation is preserved and wrap the callback in bindInvocationContext client.on('data', bindInvocationContext(async () => { await storage.set('foo', 'bar'); })); }
The latest Forge runtime might keep executing the code after the function returns. For example:
1 2resolver.define("example", () => { setTimeout(() => { fetch("..."); }, 5000); });
In this example, timers and other asynchronous code may continue executing even after the Forge function returns a response.
When making API calls through requestJira
, requestConfluence
and requestBitbucket
, outbound HTTP
requests will assume a Content-type: application/json
if a content type isn’t specified. However, this
default will not be applied to requests to external domains using the fetch
function or other HTTP clients.
All external connections must be done through HTTPS; plain HTTP or TCP
connections are not allowed. In addition, these connections will be implemented over a custom proxy which will
only allow the following https.request
options (or equivalents from third-party packages):
auth
headers
host
method
port
path
Sending a request with a body
still works, as long as you specify the correct Content-Type:
header (for example, Content-Type: application/json
for a JSON body
).
While the current runtime uses a full Node.js environment, some https
and console
methods are replaced with
custom implementations. These customizations ensure external connections and logs connect to the Forge
platform.
Outgoing connections for Forge apps currently originate from a VPC configured in the Atlassian cloud environment where the Forge functions are executed. For apps deployed in the Forge runtime, outgoing connections will originate from Atlassian’s cloud infrastructure (specifically, the IP addresses listed here).
All requests to Atlassian product APIs that return redirects to external domains are considered egress. If your app uses such redirects, you’ll need to declare those domains and add permissions for them in your manifest file:
1 2permissions: external: fetch: backend: - 'https://www.example.com'
See Runtime egress permissions for detailed instructions.
Rate this page: