.dotf File Format
The .dotf format is a structured text format designed for machine config snapshots. It's human-readable, git-diffable, and parseable by @dotformat/core. The format spec and parser/serializer API live in the core repo. This page covers usage from the CLI perspective.
Format Overview
A .dotf file is a collection of sections, each identified by a name in square brackets. Sections can contain three types of data:
- Pairs — key-value metadata
- Items — tabular data (lists with columns)
- Content — free-form text blocks
Syntax
Section Header
[section.name]Section names use dot notation for hierarchy: ai.claude.settings, apps.brew.formulae, shell.zshrc.
Key-Value Pairs
[meta]
host = MacBook-Pro
os = Darwin arm64
date = 2026-04-07Pairs appear immediately after the section header, one per line, in key = value format.
Items (Lists)
[apps.brew.formulae]
bat
eza
fd
fzfAny line that isn't a section header, key-value pair, or multiline marker is treated as an item. For tabular data with columns, use the pipe | separator:
[ssh.hosts]
github.com | [REDACTED] | [REDACTED]
gitlab.com | [REDACTED] | [REDACTED]Content Blocks
[shell.zshrc]
export PATH="$HOME/bin:$PATH"
source "$HOME/.oh-my-zsh/oh-my-zsh.sh"
plugins=(git zsh-autosuggestions zsh-syntax-highlighting)Content is free-form text that follows the section header (or pairs/items if present). It preserves whitespace and newlines.
Example .dotf File
[meta]
host = MacBook-Pro
os = Darwin arm64
date = 2026-04-07
[ai.claude.settings]
enabledPlugins = computer-use
permissions.allow = Edit,Write
[ai.claude.skills]
superskill.md
web-dev.md
[ai.ollama.models]
llama3.2:latest | 2.0 GB | 2 days ago
codellama:7b | 3.8 GB | 5 days ago
[shell.zshrc]
<<<
export PATH="$HOME/bin:$PATH"
source "$HOME/.oh-my-zsh/oh-my-zsh.sh"
>>>
[terminal.p10k]
exists = true
lines = 1247
[apps.brew.formulae]
bat
eza
fd
fzf
git
ripgrep@dotformat/core Library
The .dotf format is parsed and generated by @dotformat/core, a separate package. The CLI uses these functions:
parse(text: string): DotfDocument
Parses .dotf text into a structured document:
import { parse } from "@dotformat/core";
const doc = parse(dotfContent);
// doc.sections["meta"].pairs.host → "MacBook-Pro"
// doc.sections["shell.zshrc"].content → "export PATH=..."
// doc.sections["apps.brew.formulae"].items → [{ raw: "bat", columns: ["bat"] }, ...]stringify(doc: DotfDocument): string
Converts a structured document back to .dotf text:
import { stringify } from "@dotformat/core";
const output = stringify(doc);
// → formatted .dotf textcompare(left: DotfDocument, right: DotfDocument): DotfDiff
Computes a structured diff between two documents:
import { compare } from "@dotformat/core";
const diff = compare(docA, docB);
// Returns sections that were added, removed, or modifiedformatDiff(diff: DotfDiff, options): string
Formats a diff for human reading:
import { formatDiff } from "@dotformat/core";
const output = formatDiff(diff, {
leftLabel: "home-mac",
rightLabel: "work-mac",
color: true,
});DotfSection Type
interface DotfSection {
name: string; // Section identifier
pairs: Record<string, string>; // Key-value pairs
items: { raw: string; columns: string[] }[]; // List/tabular items
content: string | null; // Free-form text content
}
interface DotfDocument {
sections: Record<string, DotfSection>;
}Section Types in Practice
| Section Pattern | Data Type | Example |
|---|---|---|
meta | pairs | host, os, date |
ai.claude.settings | pairs | JSON field extractions |
ai.claude.skills | items | Directory listing |
ai.ollama.models | items (tabular) | Name, size, modified columns |
ssh.hosts | items (tabular) | Host, hostname, identity columns |
shell.zshrc | content | Full file text |
git.config | content | Full file text |
terminal.p10k | pairs | exists, lines (metadata-only) |
apps.raycast | pairs | installed status |
apps.brew.formulae | items | Package list |
Slim Mode
With dotfiles collect --slim, content sections are truncated to 10 lines:
[shell.zshrc]
export PATH="$HOME/bin:$PATH"
source "$HOME/.oh-my-zsh/oh-my-zsh.sh"
# ... (first 10 lines only)
... (47 more lines)This reduces file size by ~65% — useful for feeding to AI tools where full config content isn't needed but structure and key settings are.
Naming Convention
Report files follow the pattern:
<hostname>-YYYYMMDDHHMMSS.dotfExamples:
MacBook-Pro-20260407143022.dotfwork-linux-20260401080000.dotf
The timestamp prevents overwrites and enables chronological sorting.