Skip to main content

promptfmt

Auto-formatter for LLM prompt files.

PyPI License: MIT Python 3.9+

What It Does

promptfmt is an opinionated auto-formatter for LLM prompt files, similar to what Prettier does for JavaScript or Black does for Python. It normalizes whitespace, section delimiters, template variable syntax, line wrapping, and structural formatting for YAML/JSON prompt files.

After formatting, promptfmt verifies semantic equivalence -- it re-parses the formatted output and confirms that the meaning of the prompt has not changed (same messages, roles, variables, and metadata).

Installation

pip install promptfmt

Dependencies: prompttools-core >= 1.0, typer >= 0.12, rich >= 13.0, watchfiles >= 0.21

CLI Commands

promptfmt format

Format prompt files in-place or check formatting.

# Format a single file
promptfmt format prompts/greeting.yaml

# Format all prompt files in a directory (recursive)
promptfmt format prompts/

# Check only -- exit 1 if any file would change (for CI)
promptfmt format prompts/ --check

# Show a unified diff of changes
promptfmt format prompts/ --diff

# Quiet mode (no output except errors)
promptfmt format prompts/ -q

Options:

Option Default Description
--check false Check only, do not write files. Exit code 1 if changes needed.
--diff false Show unified diff of changes.
--delimiter-style ### Target delimiter style: ###, ---, ===, ***, ~~~
--variable-style double_brace Target variable syntax: double_brace, single_brace, angle_bracket
--max-line-length 120 Maximum line length for wrapping. 0 to disable.
--quiet, -q false Suppress non-error output.

promptfmt init

Generate a default .promptfmt.yaml configuration file in the current directory.

promptfmt init

This creates a .promptfmt.yaml with default settings:

# promptfmt configuration
delimiter_style: '###'
variable_style: double_brace
max_line_length: 120
wrap_style: soft
sort_metadata_keys: true
indent: 2
exclude:
  - 'vendor/**'
  - '*.generated.*'

Formatting Rules

promptfmt applies five rule categories in order:

1. Whitespace Normalization

  • Normalize line endings to LF
  • Strip trailing whitespace from every line
  • Remove leading blank lines at file start
  • Collapse 3+ consecutive blank lines to 2
  • Ensure file ends with exactly one newline

2. Delimiter Normalization

Normalizes section delimiters (---, ===, ***, ~~~) to a single consistent style. Code blocks (```) are preserved and not modified.

Supported styles: ###, ---, ===, ***, ~~~

3. Variable Syntax Normalization

Converts all template variable references to a single syntax style. Inline code spans (`code`) are preserved and not modified.

Style Syntax Example
double_brace {{var}} Hello {{name}}
single_brace {var} Hello {name}
angle_bracket <var> Hello <name>

Common HTML tags (div, span, p, br, etc.) are excluded from variable detection when using angle bracket style.

4. Line Wrapping

Wraps lines exceeding the configured maximum length at word boundaries. The following are never wrapped:

  • Lines inside code blocks
  • URL lines
  • Table rows (starting with |)
  • Heading lines (starting with #)

Leading indentation is preserved on continuation lines.

5. Structure Normalization (YAML/JSON only)

For YAML and JSON files:

  • Re-serializes with consistent indentation (default: 2 spaces)
  • Sorts metadata keys with priority ordering: model, name, description, defaults appear first, then remaining keys alphabetically
  • Within message objects, sorts keys with role before content
  • Re-applies whitespace normalization after structural changes

Configuration (.promptfmt.yaml)

Key Type Default Description
delimiter_style string "###" Target delimiter style
variable_style string "double_brace" Target variable syntax
max_line_length int 120 Max line length (0 to disable)
wrap_style string "soft" Wrapping approach
sort_metadata_keys bool true Sort keys in YAML/JSON
indent int 2 Indentation width for YAML/JSON
exclude list [] Glob patterns to exclude

Programmatic Usage

from promptfmt import format_file, format_content, FmtConfig, is_equivalent

# Format a file
config = FmtConfig(delimiter_style="---", variable_style="double_brace")
result = format_file("prompts/greeting.yaml", config)

print(result.changed)      # True if content changed
print(result.equivalent)   # True if semantically equivalent
print(result.formatted_content)

# Format raw content
from prompttools_core import PromptFormat
formatted = format_content(content, PromptFormat.YAML, config)

# Check semantic equivalence between two parsed prompts
from prompttools_core import parse_file
original = parse_file("original.yaml")
modified = parse_file("modified.yaml")
print(is_equivalent(original, modified))

CI Integration

GitHub Actions

- name: Check prompt formatting
  run: promptfmt format prompts/ --check

Pre-commit Hook

#!/bin/sh
promptfmt format prompts/ --check || exit 1

GitLab CI

check-prompt-format:
  script:
    - pip install promptfmt
    - promptfmt format prompts/ --check

Exit codes:

Code Meaning
0 All files formatted (or no changes needed)
1 Files need formatting (with --check)
2 Errors occurred during formatting

License

MIT License. Author: Scott Converse.

Metadata

Release files for promptfmt 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for promptfmt 1.0.0
File Size Uploaded Provenance Actions
promptfmt-1.0.0.tar.gz 12.6 kB Without provenance Details for promptfmt-1.0.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for promptfmt 1.0.0
File Interpreter ABI Platform Actions
promptfmt-1.0.0-py3-none-any.whl Python 3 none any Details for promptfmt-1.0.0-py3-none-any.whl

Total release size: 26.4 kB

Release files / promptfmt-1.0.0.tar.gz

Download URL promptfmt-1.0.0.tar.gz
Size 12.6 kB
Tags Source
SHA-256 checksum
How to use checksums
aaf6d00be8e132ec6f3555820b8665774832a6e74fde6f8a29c9033942e99d34
BLAKE2b-256 checksum
How to use checksums
2137b307243aee036778d8f85e8213329d2e97bef944e385393af45f010a89cf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.3

Release files / promptfmt-1.0.0-py3-none-any.whl

Download URL promptfmt-1.0.0-py3-none-any.whl
Size 13.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a19a90fb4084fa1e0f7e194644ec80ecfe6dd826108eb72363d33e1475505fd2
BLAKE2b-256 checksum
How to use checksums
bee43d5d9d9b909e3c0800adea6489963659e74a0c94950aaaede7b8a5dd8d2f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.3

Security for promptfmt 1.0.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page