Network Operations
Learn how to connect your UXP plugin to the web
UXP provides powerful network APIs that let your plugin fetch data, access online services, and communicate in real time—all while keeping users safe through a robust permission model. This guide covers how to use fetch, XMLHttpRequest, and WebSocket in UXP, how to declare network permissions properly, and how to handle errors.
System requirements
Please make make sure your development environment uses the following minimum versions to avoid compatibility issues:
- Premiere v25.6
- UDT v2.2
- Manifest v5
Network Security
By default, UXP plugins can't connect to the internet; this helps keep users safe by preventing unwanted or hidden network activity. If your plugin needs to fetch data, load images, or use WebSockets, you must declare the right network permissions.
In your plugin's manifest.json, use the requiredPermissions.network object to lists the domains your plugin can access.
Copied to your clipboard{"requiredPermissions": {"network": {"domains": ["https://api.example.com","https://*.adobe.io"]}}}
You may use wildcards for domain patterns, such as "https://api.*.example.com" to match multiple environments (for example, dev, staging, and production). Any request to an unlisted domain will fail with a permission error.
All APIs support both HTTP and HTTPS, but macOS restricts http:// for security reasons. You should use https:// instead.
Choose the right Network API
UXP supports three primary ways to perform network communication:
| API | Best For | Supported Features |
|---|---|---|
fetch | Modern, promise-based HTTP requests | JSON, text, binary data, streaming |
XMLHttpRequest | Legacy compatibility | Progress events, upload tracking |
WebSocket | Real-time communication | Persistent bidirectional data flow |
Network APIs are available globally in UXP, you don't need to import them. Let's explore each one in depth.
Using fetch()
The fetch() API is the simplest and most flexible way to make network requests. It's modern, asynchronous, and built into the UXP global scope—no require() needed.
Copied to your clipboard// Get weather forecast for San Jose ☀️async function getForecast() {try {const response = await fetch("https://api.weather.gov/gridpoints/MTR/99,82/forecast");if (!response.ok) {throw new Error(`HTTP error ${response.status}: ${response.statusText}`);}const data = await response.json(); // 👈 parse the response as JSONconsole.log(`Forecast: ${data.properties.periods[0].detailedForecast}`);} catch (err) {console.error("❌ Failed to fetch forecast:", err);}}
Copied to your clipboard{// ..."requiredPermissions": {"network": {"domains": ["https://api.weather.gov"]}}// ...}
Remember to parse the response object as json(), text(), and blob() for the appropriate data types. These methods return Promises, so you must use await to get the data.
Example: Fetching an Image Dynamically
You can even use network data directly in your UI.
Copied to your clipboard<img src="https://picsum.photos/300/200" alt="A random image" />
Copied to your clipboard{// ..."requiredPermissions": {"network": {"domains": ["https://picsum.photos/"]}}// ...}
The <img> tag works seamlessly in UXP, provided the remote domain is allow-listed.
Example: POST Requests and JSON Payloads
Many web APIs expect POST requests with JSON bodies. Here's how to send data safely.
Copied to your clipboardasync function postUserData(user) {try {const response = await fetch("https://api.example.com/users", {method: "POST",headers: { "Content-Type": "application/json" },body: JSON.stringify(user)});if (!response.ok) throw new Error(`Server error: ${response.status}`);const result = await response.json();console.log("✅ User created:", result);} catch (err) {console.error("Failed to post user data:", err);}}// Example usagepostUserData({ name: "Jamie", role: "Editor" });
UXP is not a browser environment
We have mentioned this before; some features you're familiar with are not available. For example, you can't use the TextDecoder class to read a data stream.
Copied to your clipboardasync function fetchStreamedData() {const response = await fetch("https://api.example.com/stream");const reader = response.body.getReader();const decoder = new TextDecoder(); // ❌ decoder is undefined here!!// ...}
Using XMLHttpRequest (XHR)
XMLHttpRequest is the older, event-driven API. It's still useful when you need progress events or upload monitoring.
Copied to your clipboardfunction getForecastWithXHR() {const xhr = new XMLHttpRequest();xhr.open("GET","https://api.weather.gov/gridpoints/MTR/99,82/forecast");xhr.responseType = "json";xhr.onload = () => {if (xhr.status === 200) {console.log(`Forecast: ${xhr.response.properties.periods[0].detailedForecast}`);} else {console.error(`XHR failed with status ${xhr.status}`);}};xhr.onerror = () => console.error("Network error occurred");xhr.send();}
Copied to your clipboard{// ..."requiredPermissions": {"network": {"domains": ["https://api.weather.gov"]}}// ...}
Using WebSocket
WebSockets let your plugin maintain a live connection to a server—ideal for apps that need to update in real time.
Copied to your clipboardlet socket;async function connectToServer() {try {if (socket) {console.log("🔌 Disconnecting existing socket...");socket.close();socket = null;return;}socket = new WebSocket("wss://javascript.info/article/websocket/demo/hello");socket.onopen = () => {console.log("✅ WebSocket connection established");socket.send("Hello from Premiere plugin!");};socket.onmessage = (event) => {console.log(`📩 Message from server: ${event.data}`);};socket.onerror = (err) => {console.error("⚠️ WebSocket error:", err);};socket.onclose = () => {console.log("Connection closed");socket = null;};} catch (e) {console.error("Failed to connect via WebSocket:", e);}}
Copied to your clipboard{// ..."requiredPermissions": {"network": {"domains": ["wss://javascript.info"]}}// ...}
UXP supports WebSocket clients only
Plugins can connect to WebSocket servers, but cannot host or accept incoming connections.
Handling Errors and Timeouts
Network calls can fail—the user may be offline, the endpoint may be down, or your permission list might be incomplete.
Best practices:
- Always wrap network calls in
try...catchblocks. - Use
response.okto detect HTTP errors. - Set reasonable timeouts for long operations.
- Log informative errors using
console.error().
Copied to your clipboardasync function safeFetch(url, options = {}, timeoutMs = 8000) {const controller = new AbortController();const timeout = setTimeout(() => controller.abort(), timeoutMs);try {const res = await fetch(url, { ...options, signal: controller.signal });if (!res.ok) throw new Error(`HTTP ${res.status}`);return await res.json();} catch (err) {console.error("Network request failed:", err);throw err;} finally {clearTimeout(timeout);}}
Troubleshoot Common Issues
| Symptom | Likely Cause | Solution |
|---|---|---|
TypeError: Failed to fetch | Domain not allow-listed | Add the domain under requiredPermissions.network.domains |
Connection fails only on macOS | HTTPS required | Premiere disallows http:// URLs on macOS |
Request blocked by CORS | Remote server missing CORS headers | Ensure your server allows requests from UXP (check Access-Control-Allow-Origin) |
WebSocket connection closed unexpectedly | Server-side disconnect | Check for idle timeout or SSL misconfiguration |
Reference Material
fetchAPI Reference.XMLHttpRequestReference.WebSocketReference.- Manifest Permissions.
- Network Permission Details.
Summary
- Network Security Model: By default, UXP plugins cannot access the internet. All network operations require explicit declaration of permitted domains in the
manifest.jsonfile underrequiredPermissionsto prevent unwanted network activity.- Add specific domains to the
domainsarray (e.g.,"https://api.example.com"). - Use wildcards for flexible domain patterns (e.g.,
"https://*.adobe.io"), - Any request to an unlisted domain will fail with a permission error,
- On macOS,
http://URLs are restricted for security reasons; usehttps://instead.
- Add specific domains to the
- Three Network APIs: Choose based on your use case:
fetch(): Modern, promise-based API for HTTP requests; supports JSON, text, binary data, and streaming; ideal for most use cases.XMLHttpRequest: Legacy, event-driven API; useful for progress events and upload tracking; provides compatibility with older code patterns.WebSocket: Real-time, bidirectional communication; maintains persistent connections to servers; client-only (plugins cannot host WebSocket servers).

