Skip to main content

Getting Started

Setup

1. Create a config file

Navigate to your project root and run:

dfmt --init snowflake

This creates a .dfmt.json file:

{
"dialect": "snowflake",
"keywordCase": "lower",
"identifierCase": "preserve",
"functionCase": "lower",
"dataTypeCase": "lower",
"maxLineWidth": 80,
"indentWidth": 4,
"commaStyle": "trailing",
"include": ["**.sql"],
"exclude": []
}

The .dfmt.json file marks your project root. All paths in include/exclude are relative to this file.

2. Configure include/exclude patterns

Edit the include and exclude arrays to match your project structure:

{
"include": ["models/**/*.sql", "macros/**/*.sql"],
"exclude": ["**/temp/**"]
}

3. Format

# Preview (prints formatted output, doesn't write)
dfmt

# Write changes back
dfmt --write

# Check only (CI mode)
dfmt --check

dbt Projects

dfmt automatically detects dbt projects when dbt_project.yml is found. In a dbt project:

  • The dialect is inferred from the dbt adapter (e.g., snowflake from dbt-snowflake)
  • Models are formatted with Jinja awareness -- {{ ref() }}, {% if %}, macros are preserved
  • The Jinja template is evaluated internally (no dbt compile needed), then SQL is formatted, then Jinja constructs are restored
# In a dbt project directory
dfmt --init # creates .dfmt.json
dfmt --write # formats all models
dfmt --model my_model # formats a single model

Common Workflows

Format only changed files

# Format files changed since main branch
dfmt --changed-since main --write

# Format files changed since last commit
dfmt --changed-since HEAD~1 --write

Quick format without config (yolo mode)

# Format a single file without .dfmt.json
dfmt --dialect postgres query.sql

# Format a directory
dfmt --dialect bigquery queries/

Override config options from CLI

# Use uppercase keywords regardless of config
dfmt --write --uppercase

# Use narrower line width
dfmt --write --width 100