Skip to content

Getting Started Tutorial

Step-by-step tutorial for building your first Dataface dashboard from SQL.


Prerequisites Check

Before starting, ensure you have:

  • ✅ Dataface installed (dft --version — see Installation)
  • ✅ A database Dataface can query — Postgres, Snowflake, BigQuery, DuckDB, SQLite, or a local CSV/Parquet file

You do not need dbt or a Semantic Layer to build dashboards. Most projects start with plain SQL. If you already run dbt and want governed metrics, the MetricFlow integration is an optional upgrade you can adopt later.


Step 1: Set Up Project Structure

Dataface dashboards ("faces") live in a faces/ directory. A minimal project is just that directory plus a dataface.yml that names your data source:

my-project/
├── dataface.yml            # Names your data source(s)
├── faces/                  # Your dashboards here
│   └── my_first_dashboard.yml
└── assets/                 # Optional: images, CSV data files
    ├── images/
    └── data/

Point dataface.yml at a database. A local DuckDB file needs no credentials, which makes it the quickest way to start:

# dataface.yml
sources:
  analytics:
    type: duckdb
    path: ./data/analytics.duckdb

See Sources for Postgres, Snowflake, BigQuery, and dbt profile connections.


Step 2: Create a Dashboard File

Create faces/my_first_dashboard.yml with a title and the source it reads from:

title: "My First Dashboard"

source: analytics

The face-level source: applies to every query in the dashboard, so you don't repeat it on each one.


Step 3: Define a Query

Add a SQL query that returns the columns you want to chart:

title: "My First Dashboard"

source: analytics

queries:
  sales:
    sql: |
      SELECT
        date_trunc('month', ordered_at) AS month,
        SUM(amount) AS revenue,
        COUNT(*) AS orders
      FROM orders
      GROUP BY 1
      ORDER BY 1

The query owns the data: its grain, aggregation, and ordering. Each query has a name (sales) and returns named columns (month, revenue, orders) that charts bind to.


Step 4: Create a Chart

Add a chart that maps query columns to visual channels:

title: "My First Dashboard"

source: analytics

queries:
  sales:
    sql: |
      SELECT
        date_trunc('month', ordered_at) AS month,
        SUM(amount) AS revenue,
        COUNT(*) AS orders
      FROM orders
      GROUP BY 1
      ORDER BY 1

charts:
  revenue_chart:
    title: "Revenue by Month"
    query: sales
    type: bar
    x: month
    y: revenue

The chart doesn't aggregate or infer anything — the query already did that. The chart only decides that month goes on the x-axis and revenue on the y-axis.


Step 5: Organize with Layouts

Layouts arrange your charts. Use rows to stack, cols to place side by side, or grid for precise columns:

rows:
  - title: "Sales Overview"
    cols:
      - revenue_chart
      - orders_chart

Step 6: Validate and Preview

Validate the dashboard:

dft validate faces/my_first_dashboard.yml

Fix any errors it reports, then start a live preview:

dft serve

Open the URL dft serve prints on startup to see your dashboard. It re-renders as you edit the YAML.


Step 7: Add Variables

Variables are the controls readers use to filter a dashboard. Wire one into the query with the filter() helper — it writes the SQL predicate for the selected value, or a no-op when nothing is selected:

title: "My First Dashboard"

source: analytics

variables:
  region:
    input: select
    options:
      static: ["North", "South", "East", "West"]
    # No default: starts on All regions

queries:
  sales:
    sql: |
      SELECT
        date_trunc('month', ordered_at) AS month,
        SUM(amount) AS revenue,
        COUNT(*) AS orders
      FROM orders
      WHERE {{ filter('region', region) }}
      GROUP BY 1
      ORDER BY 1

charts:
  revenue_chart:
    title: "Revenue by Month"
    query: sales
    type: bar
    x: month
    y: revenue

rows:
  - title: "Sales Overview"
    cols:
      - revenue_chart

Now the region selector filters the chart. A variable never filters data on its own — you always wire it into a query explicitly.


Step 8: Add More Charts

Add another chart and place both in a grid:

charts:
  revenue_chart:
    title: "Revenue by Month"
    query: sales
    type: bar
    x: month
    y: revenue

  orders_chart:
    title: "Orders by Month"
    query: sales
    type: line
    x: month
    y: orders

rows:
  - title: "Sales Overview"
    grid:
      columns: 24
      items:
        - item: revenue_chart
          width: 12
        - item: orders_chart
          width: 12

Complete Example

Here's the full dashboard, with both charts split by region:

title: "My First Dashboard"

source: analytics

variables:
  region:
    input: select
    options:
      static: ["North", "South", "East", "West"]
    # No default: starts on All regions

queries:
  sales:
    sql: |
      SELECT
        date_trunc('month', ordered_at) AS month,
        region,
        SUM(amount) AS revenue,
        COUNT(*) AS orders
      FROM orders
      WHERE {{ filter('region', region) }}
      GROUP BY 1, 2
      ORDER BY 1

charts:
  revenue_chart:
    title: "Revenue by Month"
    query: sales
    type: bar
    x: month
    y: revenue
    color: region

  orders_chart:
    title: "Orders by Month"
    query: sales
    type: line
    x: month
    y: orders
    color: region

rows:
  - title: "Sales Overview"
    grid:
      columns: 24
      items:
        - item: revenue_chart
          width: 12
        - item: orders_chart
          width: 12

Next Steps

Now that you've built your first dashboard:

  1. Read the Queries Guide — SQL, values, files, HTTP, dbt models, and MetricFlow
  2. Read the Charts Guide — explore chart types and options
  3. Read the Variables Guide — add more interactive filters
  4. See Examples — explore complete dashboards
  5. Best Practices — dashboard design best practices

Common Questions

How do I know which tables and columns are available?

Use dft query against INFORMATION_SCHEMA to browse your source's tables and columns without leaving the terminal:

dft query mydb "SELECT table_schema, table_name FROM INFORMATION_SCHEMA.TABLES"

Can I use dbt metrics instead of SQL?

Yes. If your dbt project has a Semantic Layer, a query can use metrics:/dimensions: instead of sql:. See MetricFlow.

Can I use multiple queries?

Yes — define multiple queries and reference them from different charts.

How do I add more rows?

Add more items to the rows array. Each row can have its own cols or grid.

Can I customize colors and styling?

Yes. See the Styling Guide for themes and styling options.