---
title: Apps
description: >-
  Build and deploy custom Apps locally using a code-based development workflow
  with React, backend functions, and a CLI.
breadcrumbs: Docs > Actions > Apps
---

# Apps

{% callout %}
# Important note for users on the following Datadog sites: app.ddog-gov.com, us2.ddog-gov.com

{% alert level="danger" %}
This product is not supported for your selected [Datadog site](https://docs.datadoghq.com/getting_started/site.md). ({% placeholder "user-datadog-site-name" /%}).
{% /alert %}

{% /callout %}

{% callout %}
# Important note for users on the following Datadog sites: app.datadoghq.com, us3.datadoghq.com, us5.datadoghq.com, app.datadoghq.eu, ap1.datadoghq.com, ap2.datadoghq.com, uk1.datadoghq.com

{% callout %}
##### Join the Preview!

Datadog Apps is in Preview. Use this form to request access.

[Request Access](https://www.datadoghq.com/product-preview/apps/)
{% /callout %}

{% /callout %}

## Overview{% #overview %}

With Apps, you build applications locally as code with React and TypeScript (or JavaScript), using your standard development workflow.

Apps use the same [permissions model](https://docs.datadoghq.com/actions/app_builder/access_and_auth.md) as [App Builder apps](https://docs.datadoghq.com/actions/app_builder.md). You can also embed them in other Datadog products, such as [dashboards and the Internal Developer Portal](https://docs.datadoghq.com/actions/app_builder/embedded_apps.md).

Choose Apps when you need:

- **Team collaboration**: Multiple engineers contributing to the same app, with code review and version history through your existing source control.
- **Source control and CI/CD**: Store your app in GitHub and deploy automatically on merge.
- **AI-assisted development**: Use your preferred local tooling (such as Cursor, GitHub Copilot, or Claude) to generate and refine code.
- **Custom cloud providers and APIs**: Integrate with services beyond the [Action Catalog](https://docs.datadoghq.com/actions/actions_catalog.md) using your own backend code.
- **Complex UI and logic**: Full React and TypeScript control over components, state, and rendering.

## Prerequisites{% #prerequisites %}

- **Node.js version 20.12.0 or later**. Check your version:

  ```shell
  node --version
  ```

- Optional: A Datadog **API key** and an **application key** with [Actions API Access](https://docs.datadoghq.com/account_management/api-app-keys.md#actions-api-access) enabled. Required for API-key-backed build telemetry (build metrics and Error Tracking sourcemap uploads) and for CI/CD uploads. For instructions, see [API and Application Keys](https://docs.datadoghq.com/account_management/api-app-keys.md).

To enable Actions API Access on an application key:

  1. Navigate to [**Organization Settings > Application Keys**](https://app.datadoghq.com/organization-settings/application-keys).
  1. Select your application key.
  1. Enable **Actions API Access**.

## Scaffold an app{% #scaffold-an-app %}

1. Run the scaffolding command to create an app:
   ```shell
   npm create @datadog/apps@latest
   ```
1. Follow the interactive prompts to configure your app name and template.

### Generated app structure{% #generated-app-structure %}

The scaffolded project includes:

| File or directory     | Description                                                                                                                    |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| `src/App.tsx`         | Root UI component (React)                                                                                                      |
| `src/**/*.backend.ts` | Backend functions that run server-side with access to [Datadog connections](https://docs.datadoghq.com/actions/connections.md) |
| `vite.config.ts`      | Build configuration with [`@datadog/vite-plugin`](https://github.com/DataDog/build-plugin) pre-configured                      |
| `package.json`        | Dependencies and scripts (`dev`, `build`, `upload`)                                                                            |

## Use the `datadog-app` skill{% #use-the-datadog-app-skill %}

The [`datadog-app` agent skill](https://github.com/datadog-labs/agent-skills/tree/main/dd-apps/datadog-app) gives AI coding agents guidance on Datadog Apps workflows, including scaffolding, local development, uploads, publishing, CI/CD, troubleshooting, DDSQL, and Action Catalog usage. The skill is available in the [agent-skills GitHub repository](https://github.com/datadog-labs/agent-skills/blob/main/README.md).

### Install{% #install %}

```shell
npx skills add datadog-labs/agent-skills \
  --skill datadog-app \
  --full-depth -y
```

The `skills` CLI supports Claude Code, Codex, Cursor, Gemini CLI, OpenCode, and other coding agents. To target a specific agent, see the [skills CLI documentation](https://github.com/antfu/skills-cli). If the skill does not appear after installation, restart your coding agent.

### Example prompts{% #example-prompts %}

- `Scaffold a Datadog App called my-app.`
- `Run this Datadog App locally.`
- `Upload and publish this Datadog App.`
- `Set up CI/CD for this Datadog App.`
- `Troubleshoot this Datadog App authentication error.`

## Develop your app locally{% #develop-your-app-locally %}

1. Start the development server:
   ```shell
   npm run dev
   ```
1. Open the URL shown in the terminal (for example, `http://localhost:5173/`) to preview your app.

When the dev server needs to call Datadog, such as when running a backend function locally, it uses OAuth by default. If authorization is required, the command opens a browser prompt. After authorization completes, the token is cached in your operating system credential store.

If you set both `DD_API_KEY` and `DD_APP_KEY`, the generated app uses those keys instead of OAuth.

### Backend functions{% #backend-functions %}

Files matching `*.backend.ts` or `*.backend.js` contain backend functions. Backend functions run server-side with access to your [connections](https://docs.datadoghq.com/actions/connections.md). The frontend imports and calls them like standard ES modules.

Backend functions can call any action in Datadog's [Action Catalog](https://docs.datadoghq.com/actions/actions_catalog.md) through the [`@datadog/action-catalog`](https://www.npmjs.com/package/@datadog/action-catalog) library. The Action Catalog provides reusable, prebuilt actions for interacting with cloud providers, SaaS tools, and the Datadog API. You can build on top of existing integrations instead of writing API clients from scratch.

The library is a fully typed TypeScript client that wraps integrations, including AWS, Azure, GCP, the Datadog API, GitHub, GitLab, Slack, Jira, PagerDuty, ServiceNow, OpenAI, Anthropic, and generic HTTP. Importing actions from `@datadog/action-catalog` gives you typed inputs and responses for each action.

{% collapsible-section %}
#### Example backend function

Create a backend function that lists hosts through the Action Catalog:

**src/listHosts.backend.ts**

```typescript
import { listHosts, type ListHostsResponse } from '@datadog/action-catalog/dd/hosts';

export async function getHosts(filter?: string): Promise<ListHostsResponse> {
    const response = await listHosts({
        inputs: {
            filter: filter ?? '*',
            count: 10,
            include_hosts_metadata: true,
        },
    });
    return response;
}
```

Then call it from your app's `App.tsx`:

**src/App.tsx**

```tsx
import { useState, useEffect } from 'react';
import { getHosts } from './listHosts.backend';

function App() {
    const [hostCount, setHostCount] = useState<number>(0);

    useEffect(() => {
        getHosts().then((response) => {
            setHostCount(response.host_list?.length ?? 0);
        });
    }, []);

    return (
        <div style={{ padding: '2rem', textAlign: 'center' }}>
            <h1>Welcome to my-app</h1>
            <p>Monitoring {hostCount} hosts</p>
        </div>
    );
}

export default App;
```

{% /collapsible-section %}

## Build and upload your app{% #build-and-upload-your-app %}

Use `npm run build` to build the app locally without uploading it. This is the recommended default for local development, where you typically don't want to upload every build.

Use `npm run upload` to build and upload the app to Datadog. This runs `vite build` with `DD_APPS_UPLOAD_ASSETS=1`.

```shell
npm run upload
```

Uploads use OAuth by default and may open a browser authorization flow the first time. If you set both `DD_API_KEY` and `DD_APP_KEY`, uploads use API and application key authentication instead.

The following environment variables are available:

| Variable                | Description                                                                                                                                                                                  |
| ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `DD_API_KEY`            | Optional. Datadog API key used with `DD_APP_KEY` for local development and uploads. Also enables API-key-backed build telemetry, such as build metrics and Error Tracking sourcemap uploads. |
| `DD_APP_KEY`            | Optional. Application key used with `DD_API_KEY` for local development and uploads.                                                                                                          |
| `DD_APPS_AUTH_METHOD`   | Optional. Set to `oauth` or `apiKey` to override the generated app's authentication method.                                                                                                  |
| `DD_APPS_VERSION_NAME`  | Optional. The version name for the uploaded app version. Must be a unique string per app. If unset, Datadog assigns a version name.                                                          |
| `DD_APPS_UPLOAD_ASSETS` | If set, uploads built assets to Datadog. Set automatically by `npm run upload`.                                                                                                              |

For production deployments, set up CI/CD with GitHub Actions. [`DataDog/apps-github-action`](https://github.com/DataDog/apps-github-action) handles the upload step for you.

After a successful upload, the build output displays a URL where your app is accessible in Datadog.

## Publish and manage your apps{% #publish-and-manage-your-apps %}

After you upload an app, it appears in your [App Builder](https://app.datadoghq.com/app-builder/apps/list) app list. From App Builder, you can:

- [Publish your app](https://docs.datadoghq.com/actions/app_builder/build.md#customize-your-app)
- [Edit the app name and description](https://docs.datadoghq.com/actions/app_builder/build.md#customize-your-app)
- Manage [permissions](https://docs.datadoghq.com/actions/app_builder/access_and_auth.md#app-permissions)
- [Embed the app](https://docs.datadoghq.com/actions/app_builder/embedded_apps.md) in dashboards, notebooks, and the Internal Developer Portal

{% alert level="danger" %}
The following App Builder features are not available for locally-built apps:
- UI editing with drag-and-drop components
- Variables, events, and expressions managed in the App Builder UI
To change an app's UI or logic, update the code in your local project and re-upload.
{% /alert %}

## Set up CI/CD with GitHub Actions{% #set-up-cicd-with-github-actions %}

To automatically upload your app on every push to the `main` branch, use the [`DataDog/apps-github-action`](https://github.com/DataDog/apps-github-action) GitHub Action. This action builds your app and uploads it to Datadog.

CI/CD uploads require API and application key authentication. Create a Datadog API key and an application key with [Actions API Access](https://docs.datadoghq.com/account_management/api-app-keys.md#actions-api-access) enabled, then store them as GitHub secrets.

If your organization is not on US1 (`datadoghq.com`), set `auth.site` in `vite.config.ts` to your [Datadog site](https://docs.datadoghq.com/getting_started/site.md). The build reads this configuration when uploading the app, so the same setting also applies to local development. Your Datadog site is ``.

{% callout %}
# Important note for users on the following Datadog sites: us3.datadoghq.com, us5.datadoghq.com, app.datadoghq.eu, ap1.datadoghq.com, ap2.datadoghq.com, uk1.datadoghq.com



```ts
datadogVitePlugin({
  auth: {
    site: '<YOUR_DATADOG_SITE>',
  },
});
```


{% /callout %}

Create `.github/workflows/cd.yml` in your app's repository:

```yaml
name: Continuous Deployment
on:
  push:
    branches:
      - main

permissions:
  contents: read

jobs:
  deploy-app:
    name: Deploy Datadog App
    runs-on: ubuntu-latest
    permissions:
      contents: read
      id-token: write

    steps:
      - name: Checkout
        uses: actions/checkout@v6

      - name: Setup Node.js
        uses: actions/setup-node@v6

      - name: Deploy
        uses: DataDog/apps-github-action@v0.0.2
        with:
          datadog-api-key: ${{ secrets.DATADOG_API_KEY }}
          datadog-app-key: ${{ secrets.DATADOG_APP_KEY }}
          app-directory: .
```

## Troubleshooting{% #troubleshooting %}

### Authentication errors{% #authentication-errors %}

For local development and uploads, OAuth authentication errors may have one of these causes:

- The OAuth browser flow did not complete.
- The cached OAuth token is invalid.
- `auth.site` does not match your Datadog site.

Rerun the command and complete the browser authorization flow.

If you use API and application key authentication, authentication errors usually point to missing or invalid credentials. Backend function call failures can have the same cause. Verify that `DD_API_KEY` and `DD_APP_KEY` are set, and that the application key has [Actions API Access](https://docs.datadoghq.com/account_management/api-app-keys.md#actions-api-access) enabled.

### Build succeeds but nothing uploads{% #build-succeeds-but-nothing-uploads %}

Make sure you ran `npm run upload` (not `npm run build`), and that `dryRun` in `vite.config.ts` is not set to `true`.

### Node.js version errors during scaffolding{% #nodejs-version-errors-during-scaffolding %}

The scaffolding tool requires Node.js 20.12.0 or later. If you see errors even on a supported version, upgrade to v22. Use a version manager such as [nvm](https://github.com/nvm-sh/nvm), [Volta](https://volta.sh), or [fnm](https://github.com/Schniz/fnm), or download from the [Node.js website](https://nodejs.org).

## Further reading{% #further-reading %}

- [Ship internal applications from your AI Agent with Datadog Apps](https://www.datadoghq.com/blog/internal-applications-datadog-apps/)
- [App Builder](https://docs.datadoghq.com/actions/app_builder.md)
- [Embedded Apps](https://docs.datadoghq.com/actions/app_builder/embedded_apps.md)
- [Access and Authentication](https://docs.datadoghq.com/actions/app_builder/access_and_auth.md)
