šŸŽ® Foundations — Module 1

Setting Up Your BFG

Tutorial

Your BFG — The dt-app CLI

Every Dynatrace app starts with one command. The dt-app CLI scaffolds projects, runs the dev server, builds bundles, and deploys to your environment. No global install needed — npx handles it.

# Verify Node.js (22+ required)
node --version

# Create a new app
npx dt-app@latest create --environment-url https://YOUR-ENV.apps.dynatrace.com

The CLI asks for an app name, creates the project directory, installs dependencies, and generates the full scaffold. Takes about 30 seconds.

Project Structure

my-first-app/
ā”œā”€ā”€ ui/                          ← Frontend (React + TypeScript)
│   ā”œā”€ā”€ app/
│   │   ā”œā”€ā”€ App.tsx              ← Root component + routing
│   │   └── pages/
│   │       └── Home.tsx         ← Default page
│   └── assets/                  ← Static files (images, etc.)
ā”œā”€ā”€ api/                         ← Backend (serverless functions)
ā”œā”€ā”€ app.config.json              ← App metadata, scopes, CSP
ā”œā”€ā”€ package.json                 ← Dependencies
└── tsconfig.json                ← TypeScript config

The split is clean: ui/ is your React frontend, api/ is your serverless backend. The app.config.json ties everything together.

app.config.json — The Control Center

{
  "environmentUrl": "https://abc12345.apps.dynatrace.com",
  "app": {
    "name": "My First App",
    "version": "0.0.1",
    "description": "Learning Dynatrace app development",
    "id": "my.first.app",
    "scopes": [
      { "name": "storage:metrics:read", "comment": "Read metric data via DQL" },
      { "name": "storage:entities:read", "comment": "Read entity data" }
    ]
  }
}

Key fields:

  • environmentUrl — Your DT apps URL. Format: https://{id}.apps.dynatrace.com (production) or https://{id}.apps.dynatracelabs.com (sprint)
  • app.id — Reverse-DNS identifier. Must be unique within your environment.
  • app.scopes — Permissions your app requests. Without the right scopes, DQL queries return empty or errors.

Common Scopes

storage:metrics:read      — Query metrics via DQL timeseries
storage:entities:read     — Query entities via DQL fetch
storage:logs:read         — Query logs
storage:events:read       — Query events
storage:buckets:read      — Access Grail buckets
app-engine:apps:run       — Required for all apps

Key Dependencies

{
  "dependencies": {
    "@dynatrace/strato-components": "^1.x",
    "@dynatrace-sdk/react-hooks": "^1.x",
    "@dynatrace-sdk/navigation": "^1.x",
    "react": "^18.x",
    "react-router-dom": "^6.x"
  }
}
  • @dynatrace/strato-components — The full UI component library. Page layouts, DataTable, charts, buttons, typography — everything. The old strato-components-preview package is deprecated.
  • @dynatrace-sdk/react-hooks — React hooks for DQL queries (useDql) and app functions (useAppFunction).
  • @dynatrace-sdk/navigation — Navigation between apps and intents.

Starting the Dev Server

cd my-first-app
npx dt-app dev

This starts a local dev server (ports 3000-3005) and opens your browser. The dev server proxies all API calls to your Dynatrace environment, so useDql queries hit real data immediately. Hot reload is built in.

Environment URL Formats

Apps URL:    https://{id}.apps.dynatrace.com      ← for dt-app CLI
API URL:     https://{id}.live.dynatrace.com       ← for REST API calls
Sprint:      https://{id}.apps.dynatracelabs.com   ← sprint apps URL

The app.config.json always uses the apps URL. API tokens and REST calls use the live URL.

What's Next

In Module 2, we write actual code — creating pages, adding Strato components, and getting your first app rendering in the browser. First blood.