Generated banner for App SDK Concepts
Generated logo for App SDK Concepts

App SDK Concepts

Grafana LabsOfficialPublished by Grafana Labs

  • Skill
  • Tool integration
  • Cloud and DevOps
  • Apache-2.0
  • Medium risk

From the author

Use when starting any grafana-app-sdk work — scaffolding a Grafana app, initializing a Grafana App Platform app, picking a deployment mode (standalone operator / grafana/apps / frontend-only), wiring app-specific config, or onboarding to the SDK. Covers `grafana-app-sdk` CLI install, `project init` per deployment mode, project layout, the schema-centric workflow (CUE kinds → generated code → reconciler/admission logic), and `SpecificConfig` for env-driven app configuration. Use even if the user just says "make a new app", "Grafana app platform", "kinds and watchers", "operator scaffold", or asks about `apps/` inside the Grafana repo, without naming the SDK explicitly.
— the description by Grafana Labs

AutoGineer summary

Written by AutoGineer from the skill’s own files, not by the author

The grafana-app-sdk provides a CLI and Go library for building schema-centric applications on the Grafana App Platform. It supports a workflow where developers define resources using CUE schemas, generate Go and TypeScript code, and implement business logic through reconcilers and admission controllers. The SDK supports multiple deployment modes, including standalone Kubernetes operators and in-process applications within the Grafana repository.

What it does

  • Initializes new application projects with the required directory structure and build files
  • Scaffolds Kubernetes operator components or frontend plugin structures
  • Generates Go types, clients, and TypeScript definitions from CUE schemas
  • Provides commands for local development and testing of application logic
  • Facilitates the creation of Kubernetes YAML bundles for deployment
  • Supports configuration management for environment-driven application settings

When to use it

  • When starting a new project on the Grafana App Platform
  • When you need to define custom resources using CUE schemas
  • When building a standalone Kubernetes operator for Grafana-related tasks
  • When integrating a new application directly into the Grafana repository
  • When you need to generate boilerplate code for reconcilers and admission handlers

Advantages

  • Ensures consistent project structure across different deployment modes
  • Automates the generation of boilerplate code from schema definitions
  • Simplifies the integration of business logic with Kubernetes-style resources
  • Provides a unified CLI for the entire development lifecycle
  • Supports both standalone and in-process deployment architectures

Usage examples

“How do I start a new Grafana app project?”
Use the command grafana-app-sdk project init github.com/your-org/your-app to create the project structure, including kinds, package skeletons, and build files.
“How do I add an operator to my project?”
Run grafana-app-sdk project component add operator to scaffold the necessary reconciler stubs, admission handlers, and the operator entrypoint.
“How do I update my Go types after changing a CUE schema?”
Execute the command grafana-app-sdk generate to update Go types, clients, and TypeScript definitions based on your latest CUE definitions.
“How do I run my app locally?”
Use the command grafana-app-sdk local/up to start a local Kubernetes-compatible API server for testing your application logic.

Install

  1. Download the skill as a ZIP:

    https://mp-staging.autogineer.com/agent-skills/grafana/app-sdk-concepts/download
  2. Unzip it into the cross-client skills folder of your project:

    mkdir -p .agents/skills && unzip app-sdk-concepts.zip -d .agents/skills

Documentation by Grafana Labs

Grafana App SDK Concepts

The grafana-app-sdk is a CLI + Go library for building schema-centric apps on the Grafana App Platform. Apps define resources via CUE schemas ("kinds"), generate Go + TypeScript code, and implement business logic via admission control and reconcilers.

Prerequisites

go install github.com/grafana/grafana-app-sdk/cmd/grafana-app-sdk@latest
grafana-app-sdk version   # verify

Common Workflows

Scaffold a standalone operator app
# 1. Init the project (use the Go module path)
grafana-app-sdk project init github.com/example/my-app

# 2. Add operator scaffolding — ASK THE USER FIRST.
#    They may prefer to write app.App by hand.
grafana-app-sdk project component add operator

# 3. Verify scaffolded layout
ls pkg/app pkg/watchers cmd/operator
# Expected: app.go, watchers/<kind>.go, main.go

Common failure: forgetting go install updates the binary — verify with grafana-app-sdk version before init.

Scaffold a grafana/apps-style app (inside grafana/grafana)

Only available inside the Grafana repo (or fork) — the init command detects apps/ and pkg/registry/apps/ at the repo root.

mkdir -p apps/my-app && cd apps/my-app
grafana-app-sdk project init github.com/grafana/grafana/apps/my-app

# Keep ONLY: kinds/ pkg/ go.mod go.sum — delete everything else.
cp apps/example/Makefile       apps/my-app/Makefile
cp apps/example/kinds/config.cue apps/my-app/kinds/config.cue   # overwrite
go work use ./apps/my-app

Then register the app inside Grafana (pkg/registry/apps/apps.go + register.go). Full walkthrough in references/deployment-modes.md.

End-to-end development loop
1. project init               → module, Makefile, kinds/
2. project kind add MyKind    → CUE kind scaffold
3. Edit kinds/*.cue           → schemas, validation, versions
4. grafana-app-sdk generate   → Go types, clients, TS types, AppManifest, CRDs
5. Implement logic            → fill in reconciler / admission stubs
6. (optional) project component add frontend

Always rerun generate after every CUE change — generated code is the API your reconciler sees.

Deployment modes (one-line table)

ModeWhen to pickWhere it runs
Standalone operatorOutside Grafana repo, want your own binaryKubernetes operator with its own webhook server
grafana/appsInside github.com/grafana/grafana (or fork)In-process inside Grafana's API server
Frontend-onlyUI-only app, no Go logic neededNo backend — TS types only

Full per-mode init, runtime, and wiring detail in references/deployment-modes.md.

References

Resources

Files

references/cli-reference.md

grafana-app-sdk CLI Reference

Installation

# Latest version
go install github.com/grafana/grafana-app-sdk/cmd/grafana-app-sdk@latest

# Specific version
go install github.com/grafana/grafana-app-sdk/cmd/[email protected]

# Verify
grafana-app-sdk version

Project Commands

project init

Initialize a new app project.

grafana-app-sdk project init <module-path>

Arguments:

  • <module-path> — Go module path (required), e.g. github.com/example/my-app

What it creates:

  • kinds/ — empty kinds directory with an initialized cue.mod

  • pkg/ — Go package skeleton

  • go.mod / go.sum — Go module files

  • Makefile — build targets including generate

  • local/ — local development config


project kind add

Add a new kind scaffold to the kinds/ directory.

grafana-app-sdk project kind add <KindName> [flags]

Arguments:

  • <KindName> — PascalCase kind name (required), e.g. IssueTracker

Flags:

FlagDescription
--overwriteOverwrite existing kind files (use when re-scaffolding)

What it creates:

  • kinds/<kindname>.cue — common kind metadata

  • kinds/<kindname>_<version>.cue — <version> schema scaffold with comments

Notes:

  • Always use --overwrite to regenerate when the scaffold changes in newer SDK versions

  • The generated file is heavily commented — read the comments carefully

  • It will always generate only a single version, the preferredVersion in manifest.cue. To add additional versions, see the cue-kind-definition skill


project component add

Add a component scaffold to an existing project.

grafana-app-sdk project component add <component>

Components:

ComponentDescription
operatorAdds operator (standalone binary) scaffolding: reconciler stubs, admission handler stubs, cmd/operator/main.go
frontendScaffolds a Grafana plugin frontend using create-plugin (requires yarn)

operator — what it creates:

cmd/
└── operator/
    └── main.go          # operator entrypoint
pkg/
├── app/
│    └── app.go           # app.App implementation stub with TODOs
└── watchers/
    └── watcher_<kind>.go # <kind> watcher with stubbed methods

frontend — what it creates:

plugin/
├── src/
│   ├── module.ts
│   └── pages/
├── package.json
└── plugin.json

Generate Command

generate

Generate Go types, TypeScript types, AppManifest, and CRD files from CUE kind definitions.

grafana-app-sdk generate [flags]

Flags:

FlagDescription
--sourcePath to CUE definitions (default: kinds/)
--configThe CUE selector of the config object (see CUE Config Object section)

What it generates:

OutputLocationControlled by
Go type structspkg/generated/<group>/<version>/types_gen.gocodegen.go.enabled
Go clientpkg/generated/<group>/<version>/zz_generated_*.gocodegen.go.enabled
TypeScript typesconfigured output dircodegen.ts.enabled
AppManifest (Go)pkg/app/appmanifest_gen.goalways
AppManifest (JSON)appmanifest.jsonalways
CRD (JSON or YAML)config/crd/CUE config output setting

⚠ Generated files must not be edited manually — they are overwritten on every generate run.


YAML Bundle Command

generate yaml-bundle

Generate a Kubernetes YAML bundle for deployment.

grafana-app-sdk generate yaml-bundle [flags]

Produces CRDs, webhook configurations, and RBAC manifests ready for kubectl apply.


Local Development

local

Commands for running the app locally with a mocked API server.

# Start the local development environment
grafana-app-sdk local/up

Starts a local Kubernetes-compatible API server for development without a full cluster.


Common Makefile Targets

Projects generated by project init include a Makefile with these targets:

TargetDescription
make generateRun grafana-app-sdk generate
make buildBuild the operator binary and/or frontend plugin
make testRun tests
make lintRun Go linter
make depsVendor in any missing go dependencies
make local/upCreate a local k3d development environment with Tilt
make local/push_operatorPust the built operator image to the local development enviroment k3d cluster
make local/deploy_pluginDeploy the latest built plugin to the local development environment's grafana
make local/downTake down the Tilt-deployed resources
make local/cleanDelete the local development environment k3d cluster

CUE Config Object

Control generation behavior via a CUE config object in your kinds. This is typically in the top-level kinds file:

// Codegen output configuration
config: {
    codegen: {
        // goModule allows explicitly setting the module path.
        // If empty the module path is read from go.mod
        // Default: ""
        goModule: ""
        // goModGenPath anchors generated Go output relative to the module root, instead of execution directory
        // Default: ""
        goModGenPath: ""
        // goGenPath sets the output directory for generated Go types.
        // Default: "pkg/generated/"
        goGenPath: "pkg/generated/"
        // tsGenPath sets the output directory for generated TypeScript types
        // Default: "plugin/src/generated/"
        tsGenPath: "plugin/src/generated/"
        // enableK8sPostProcessing runs the Kubernetes code generators after writing files.
        // This option is unnecessary when using the k8s.apiserver's DefaultAppInstaller
        // Default: false
        enableK8sPostProcessing: false
        // enableOperatorStatusGeneration toggles standard status information to be joined onto kinds' schema's status:
        // {
		//  #OperatorState: {
		// 	    // lastEvaluation is the ResourceVersion last evaluated
		// 	    lastEvaluation: string
		// 	    // state describes the state of the lastEvaluation.
		// 	    // It is limited to three possible states for machine evaluation.
		// 	    state: "success" | "in_progress" | "failed"
		// 	    // descriptiveState is an optional more descriptive state field which has no requirements on format
		// 	    descriptiveState?: string
		// 	    // details contains any extra information that is operator-specific
		// 	    details?: {
		// 		    [string]: _
		// 	    }
		//  }
		//  // operatorStates is a map of operator ID to operator state evaluations.
		//  // Any operator which consumes this kind SHOULD add its state evaluation information to this field.
		//  operatorStates?: {
		// 	    [string]: #OperatorState
		//  }
		//  // additionalFields is reserved for future use
		//  additionalFields?: {
		// 	    [string]: _
		//  }
	    // }
        // Default: true
        enableOperatorStatusGeneration: true
    }
    definitions: {
        // genManifest controls whether manifest files are written
        // Default: true
        genManifest: true
        // genCRDs controls whether CRD files are written
        // Default: true
        genCRDs: true
        // path sets where definition files are written
        // Default: "definitions"
        path: "definitions"
        // encoding determines JSON or YAML serialization of CRDs and manifest, allowed values are "json" and "yaml"
        // Default: "json"
        encoding: "json"
        // manifestVersion lets you pin the manifest schema format (legacy v1alpha1 vs default v1alpha2).
        // The v1alpha1 manifest uses CRD-compatible schemas for kinds, the v1alpha2 version contains more information but requires transformation to make kind schemas CRD-compatible.
        // Default: "v1alpha2"
        manifestVersion: "v1alpha2"
    }
}

Troubleshooting

grafana-app-sdk: command not found

The Go bin directory is not in PATH. Add it:

export PATH="$PATH:$(go env GOPATH)/bin"
generate fails with CUE errors

CUE is strict about types and constraints. Common causes:

  • Undefined field reference

  • Type mismatch (string where int expected)

  • Missing import (such as time for time.Time)

Run cue vet ./kinds/... to get more detailed error output.

generate produces no TypeScript output

Check that codegen.ts.enabled: true is set in the kind's CUE file and that an output path is configured.

go mod tidy needed after generate

After running generate, newly generated Go files may import packages not yet in go.sum. Run:

go mod tidy

Requirements and compatibility

Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta

“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.

Security

What our scanner noticed· Medium risk

  • References to credential files

A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.

Attribution and licence

Published by
Grafana Labs
Publisher
Grafana Labs (Official)
Source
grafana/skills · skills/grafana-app-sdk/app-sdk-concepts · commit 8fb72a5
Licence
Apache License 2.0 (redistribution allowed)
  • LICENSE (added by AutoGineer from LICENSE)
  • ATTRIBUTION.md (written by AutoGineer)
Synced

AutoGineer is not affiliated with or endorsed by Grafana Labs.

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download app-sdk-concepts.zip