Frontend Architecture & State
Relevant source files
The following files were used as context for generating this wiki page:
The Grafana frontend is a complex single-page application (SPA) built primarily with React and TypeScript. It follows a modular architecture where feature-specific code is organized into domains, such as dashboards, alerting, and explore, supported by a shared layer of internal packages. The architecture emphasizes a clear separation between UI components and business logic, utilizing modern state management patterns and centralized runtime services.
The system is designed to handle high-frequency data updates and complex user interactions. It leverages a robust development environment including Webpack for asset bundling and Jest for unit testing. The project adheres to strict style guides to ensure consistency across its large codebase, specifically following Airbnb's React/JSX rules while implementing its own custom patterns for styling and state handling.
Sources: AGENTS.md, contribute/style-guides/frontend.md:1-12
Core Framework and Organization
The frontend codebase is organized into several key directories located within public/app/. This structure facilitates domain-driven development by grouping features, types, and core services logically.
Project Structure
| Directory | Purpose |
|---|---|
public/app/core/ | Contains shared services, core components, and utilities used throughout the application. |
public/app/features/ | Houses feature-specific logic and UI (e.g., dashboard, alerting, explore). |
public/app/plugins/ | Contains built-in plugins, many of which are managed as separate Yarn workspaces. |
public/app/store/ | Centralized Redux store configuration. |
public/app/types/ | Global TypeScript type definitions. |
Sources: AGENTS.md:73-81, contribute/style-guides/frontend.md:213-225
Component Architecture
Grafana uses React functional components with hooks as the primary building block. The architecture follows these principles:
- Small and Focused: Components are kept small and broken down into sub-components for better maintainability.
- Named Exports: All code intended for external use is exported via named exports; default exports are avoided.
- Container Pattern: Pages or "containers" typically live in the root of a feature directory (e.g.,
features/my-feature/DashboardPage.tsx). - Sub-components: These reside within specific component folders to keep related logic together.
Sources: contribute/style-guides/frontend.md:14-16, contribute/style-guides/frontend.md:223-231, contribute/style-guides/frontend.md:237-241
State Management Patterns
Grafana has evolved its state management from traditional Redux to more modern approaches including Redux Toolkit (RTK) and RTK Query.
Data Fetching with RTK Query
RTK Query is the preferred method for data fetching. It provides automatic caching, polling mechanisms (e.g., RULE_LIST_POLL_INTERVAL_MS), and simplified loading/error state handling.
- API Slices: Defined in the
api/directory of a feature. - Auto-generated Clients: Developers are encouraged to use
@grafana/api-clientsrather than manual endpoints. - Endpoint Enhancement: If generated clients are incomplete, they are patched using
enhanceEndpointsrather than replaced.
Sources: public/app/features/alerting/unified/AGENTS.md:94-110, public/app/features/alerting/unified/AGENTS.md:113-130
Redux Toolkit
For complex UI state that is not strictly data-fetching related, Redux Toolkit is utilized.
- Slices: State is organized using
createSlice. - Immutability: State mutations in reducers or thunks are strictly forbidden.
- Selectors: Components must use state selectors to access data instead of direct slice access.
- Action Helpers: Legacy Redux code is migrated to use
actionCreatorFactoryandreducerFactoryhelpers.
Sources: contribute/style-guides/frontend.md:255-261, contribute/create-pull-request.md:52-58
State Flow Diagram
This diagram illustrates the flow of data from external APIs through the state management layer to the UI components.
The diagram shows how RTK Query handles server state while Redux Toolkit manages local application state, both feeding into React Components.
Sources: public/app/features/alerting/unified/AGENTS.md:94-110, AGENTS.md:83-84
Styling and Themes
Grafana utilizes Emotion as its CSS-in-JS solution. Traditional SASS styles are deprecated and are incrementally migrated to Emotion.
Styling Conventions
- useStyles2 Hook: This hook is used to memoize style generation and provides access to the Grafana theme.
- Composition: Developers are encouraged to use Emotion's
cxfunction to compose classes. - Layout Components: Instead of custom styled divs, standardized layout components from
@grafana/ui(such asBoxandStack) are preferred for layout and spacing.
Sources: contribute/style-guides/frontend.md:44-53, public/app/features/alerting/unified/AGENTS.md:55-70
Theming System
The GrafanaTheme2 object provides access to standardized colors, spacing, and typography. The palette is specifically designed to ensure high contrast for accessibility (A11y).
Sources: contribute/style-guides/frontend.md:44-50, contribute/create-pull-request.md:73-75
Communication and Runtime Services
The frontend interacts with the backend and runtime environment through a set of specialized packages.
| Package | Responsibility |
|---|---|
@grafana/runtime | Interfaces for runtime services like backendSrv, locationService, and global configuration. |
@grafana/data | Shared data structures, data models, and utilities (e.g., DataFrame, time formatting). |
@grafana/ui | A library of reusable UI components (Buttons, Selects, Inputs) and layout primitives. |
@grafana/scenes | The framework used for building complex dashboard-like experiences and triage views. |
Sources: contribute/style-guides/frontend.md:233-235, public/app/features/alerting/unified/AGENTS.md:231-238
API Communication Sequence
This sequence shows a standard request being made via the locationService and backendSrv.
The diagram highlights that locationService handles path prefixing automatically, while backendSrv manages the asynchronous HTTP communication.
Sources: public/app/features/alerting/unified/AGENTS.md:200-215, AGENTS.md:51-53
Development and Build Workflow
The frontend build system is powered by Node.js and Yarn. It includes hot-reloading for development and optimized production builds.
Key Development Commands
yarn install --immutable: Installs dependencies without updating the lockfile.yarn start: Starts the Webpack development server which watches for changes.yarn build: Generates production-ready assets.yarn test: Executes the Jest test suite.
Sources: contribute/developer-guide.md:75-87, AGENTS.md:21-27
Linting and Quality Control
Quality is enforced through ESLint and Prettier, often running as pre-commit hooks via lefthook. The project uses bulk suppressions (eslint-suppressions.json) to manage legacy issues while preventing new violations.
Sources: contribute/create-pull-request.md:86-98, contribute/developer-guide.md:60-64
Summary
The Grafana frontend architecture is a modern, React-based system that prioritizes modularity and type safety. By centralizing data fetching through RTK Query and adopting standardized UI components and themes, the project maintains a consistent user experience across hundreds of features and plugins. The transition from legacy Redux and SASS to RTK and Emotion reflects an ongoing commitment to modern web standards and developer efficiency.