or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

api

features

charts

charts.mdconditional-formatting.mdvisualizations.md
authorization.mdchangesets.mdcharts-as-code.mdcompiler.mddashboards.mddbt.mdee-features.mdformatting.mdparameters.mdpivot.mdprojects-spaces.mdsql-runner.mdtemplating.mdwarehouse.md
index.md
tile.json

charts-as-code.mddocs/api/features/

Charts-as-Code and Dashboards-as-Code

Infrastructure for managing charts and dashboards as code with slug-based access, versioning, and promotion workflows. Enables GitOps-style workflows for deploying content across environments with internationalization support and synchronization tracking.

Capabilities

Chart-as-Code

Versioned chart definitions with slug-based access, decoupled from UUID references for portability across environments.

type ChartAsCode = Pick<
  SavedChart,
  | 'name'
  | 'description'
  | 'tableName'
  | 'metricQuery'
  | 'chartConfig'
  | 'tableConfig'
  | 'pivotConfig'
  | 'slug'
  | 'updatedAt'
> & {
  dashboardSlug: string | undefined;
  version: number;
  spaceSlug: string;
  downloadedAt?: Date;
}

type ApiChartAsCodeListResponse = {
  status: 'ok';
  results: {
    charts: ChartAsCode[];
    languageMap?: Array<PartialDeep<ChartAsCodeLanguageMap, { recurseIntoArrays: true }> | undefined>;
    missingIds: string[];
    total: number;
    offset: number;
  };
};

type ApiChartAsCodeUpsertResponse = {
  status: 'ok';
  results: PromotionChanges;
};

Key Properties:

  • slug: Stable identifier for accessing charts across environments (instead of UUIDs)
  • version: Schema version for handling format evolution
  • spaceSlug: References parent space by slug rather than UUID
  • dashboardSlug: Optional reference to containing dashboard
  • downloadedAt: Tracks when chart was last downloaded for sync detection
  • languageMap: Internationalization support for chart labels and text

Dashboard-as-Code

Versioned dashboard definitions with slug-based tile references and filter configuration.

type DashboardAsCode = Pick<
  Dashboard,
  'name' | 'description' | 'updatedAt' | 'tabs' | 'slug'
> & {
  tiles: DashboardTileAsCode[];
  version: number;
  spaceSlug: string;
  downloadedAt?: Date;
  filters: Omit<DashboardFilters, 'dimensions'> & {
    dimensions: Omit<DashboardFilterRule, 'id'>[];
  };
}

type ApiDashboardAsCodeListResponse = {
  status: 'ok';
  results: {
    dashboards: DashboardAsCode[];
    languageMap?: Array<PartialDeep<DashboardAsCodeLanguageMap, { recurseIntoArrays: true }> | undefined>;
    missingIds: string[];
    total: number;
    offset: number;
  };
};

type ApiDashboardAsCodeUpsertResponse = {
  status: 'ok';
  results: PromotionChanges;
};

Dashboard Tiles-as-Code

Dashboard tiles with slug-based chart references and optional UUID removal for portability.

type DashboardTileAsCode = Omit<DashboardTile, 'properties' | 'uuid'> & {
  uuid: string | undefined;  // Optional for new tiles
  tileSlug: string | undefined;
  properties:
    | Pick<DashboardChartTileProperties['properties'], 'title' | 'hideTitle' | 'chartSlug' | 'chartName'>
    | DashboardMarkdownTileProperties['properties']
    | DashboardLoomTileProperties['properties'];
};

type DashboardTileWithSlug = DashboardTile & {
  tileSlug: string | undefined;
};

Chart Tile Properties:

  • chartSlug: References chart by slug (stable across environments)
  • chartName: Display name for the chart within the tile
  • title: Optional custom title override
  • hideTitle: Controls title visibility

Versioning and Schema Constants

const currentVersion = 1;  // Current schema version for charts/dashboards-as-code

Usage Examples

Downloading Charts as Code

import type { ChartAsCode, ApiChartAsCodeListResponse } from '@lightdash/common';

// Download charts from a space for version control
async function downloadChartsAsCode(spaceSlug: string): Promise<ChartAsCode[]> {
  const response: ApiChartAsCodeListResponse = await api.get(
    `/api/v1/spaces/${spaceSlug}/charts-as-code`
  );

  return response.results.charts.map(chart => ({
    ...chart,
    downloadedAt: new Date()  // Track download time for sync
  }));
}

Uploading/Upserting Charts as Code

import type { ChartAsCode, ApiChartAsCodeUpsertResponse } from '@lightdash/common';

// Upload chart definition to target environment
async function upsertChartAsCode(
  projectUuid: string,
  chart: ChartAsCode
): Promise<ApiChartAsCodeUpsertResponse> {
  // Returns PromotionChanges detailing what was created/updated
  return await api.post(`/api/v1/projects/${projectUuid}/charts-as-code`, {
    chart,
    version: chart.version
  });
}

Working with Dashboards as Code

import type { DashboardAsCode, DashboardTileAsCode } from '@lightdash/common';

// Define dashboard with slug-based references
const dashboard: DashboardAsCode = {
  name: 'Sales Dashboard',
  description: 'Key sales metrics and trends',
  slug: 'sales-dashboard',
  version: 1,
  spaceSlug: 'sales-team',
  updatedAt: new Date(),
  tiles: [
    {
      uuid: undefined,  // New tile, no UUID yet
      tileSlug: 'revenue-chart-tile',
      type: 'saved_chart',
      x: 0,
      y: 0,
      h: 10,
      w: 12,
      properties: {
        chartSlug: 'monthly-revenue',  // References chart by slug
        chartName: 'Monthly Revenue',
        title: 'Revenue Trends',
        hideTitle: false
      }
    },
    {
      uuid: undefined,
      tileSlug: 'markdown-note',
      type: 'markdown',
      x: 0,
      y: 10,
      h: 5,
      w: 12,
      properties: {
        content: '## Sales Dashboard\n\nUpdated monthly with latest data.',
        title: 'Dashboard Notes'
      }
    }
  ],
  filters: {
    dimensions: [
      {
        target: { fieldId: 'orders.created_date' },
        operator: 'inThePast',
        values: [30],
        settings: { unitOfTime: 'days' }
      }
    ]
  }
};

Internationalization Support

import type { ChartAsCodeLanguageMap, DashboardAsCodeLanguageMap } from '@lightdash/common';
import { type PartialDeep } from 'type-fest';

// Language maps provide translations for chart/dashboard text
// Note: Uses PartialDeep from type-fest to allow partial nested objects
const chartLanguageMap: PartialDeep<ChartAsCodeLanguageMap, { recurseIntoArrays: true }> = {
  'en-US': {
    name: 'Monthly Revenue',
    description: 'Revenue trends over time',
    // ... field labels and other translatable text
  },
  'es-ES': {
    name: 'Ingresos Mensuales',
    description: 'Tendencias de ingresos a lo largo del tiempo',
  }
};

JSON Schema Validation

JSON Schema objects for validating chart and dashboard definitions in CI/CD pipelines or development tools.

import chartAsCodeSchema from '@lightdash/common/schemas/json/chart-as-code-1.0.json';
import dashboardAsCodeSchema from '@lightdash/common/schemas/json/dashboard-as-code-1.0.json';
import modelAsCodeSchema from '@lightdash/common/schemas/json/model-as-code-1.0.json';
import lightdashDbtYamlSchema from '@lightdash/common/schemas/json/lightdash-dbt-2.0.json';
import lightdashProjectConfigSchema from '@lightdash/common/schemas/json/lightdash-project-config-1.0.json';

// These are standard JSON Schema objects that can be used with:
// - ajv (JSON Schema validator)
// - VS Code YAML/JSON schema associations
// - CI/CD validation pipelines
// - Development tooling for autocomplete and validation

Available Schemas:

  • chartAsCodeSchema: Validates chart-as-code YAML/JSON files (version 1.0)
  • dashboardAsCodeSchema: Validates dashboard-as-code YAML/JSON files (version 1.0)
  • modelAsCodeSchema: Validates model-as-code YAML/JSON definitions (version 1.0)
  • lightdashDbtYamlSchema: Validates lightdash.yml dbt schema files (version 2.0)
  • lightdashProjectConfigSchema: Validates lightdash_config.yml project config files (version 1.0)

Usage Example with AJV:

// External dependency - Install separately: npm install ajv
import Ajv from 'ajv';
import chartAsCodeSchema from '@lightdash/common/schemas/json/chart-as-code-1.0.json';

const ajv = new Ajv();
const validate = ajv.compile(chartAsCodeSchema);

// Validate a chart definition
const chartData = {
  name: 'My Chart',
  version: 1,
  spaceSlug: 'analytics',
  // ... rest of chart definition
};

if (validate(chartData)) {
  console.log('Valid chart definition');
} else {
  console.error('Validation errors:', validate.errors);
}

VS Code Schema Association Example:

// In .vscode/settings.json
{
  "yaml.schemas": {
    "./node_modules/@lightdash/common/dist/schemas/json/chart-as-code-1.0.json": "charts/*.chart.yml",
    "./node_modules/@lightdash/common/dist/schemas/json/dashboard-as-code-1.0.json": "dashboards/*.dashboard.yml"
  }
}

Integration Points

  • GitOps Workflows: Store chart/dashboard definitions in version control
  • Environment Promotion: Deploy content from dev → staging → production
  • Slug-Based References: Stable identifiers that work across environment boundaries
  • Sync Detection: downloadedAt and updatedAt timestamps detect out-of-sync content
  • Promotion API: Returns PromotionChanges detailing what was created/updated/skipped
  • Internationalization: Optional language maps for multi-language deployments
  • JSON Schema Validation: Export and validate definitions using standard JSON Schemas