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.,
snowflakefromdbt-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