Formatters
Formatters automatically format code that the LLM writes, ensuring consistency with your project's code style. When enabled, files are formatted after the model writes or edits them, before they are presented in the diff or saved.
Enabling Formatters
Enable All Built-in Formatters
The simplest way to enable formatting is to set formatter to true in opencode.json:
{
"formatter": true
}
This enables all built-in formatters that are applicable to your project's file types.
Disable Formatters Completely
{
"formatter": false
}
Built-in Formatters
opencode includes built-in formatters for the most common languages and tools. When formatter is true, all applicable formatters are active.
| Formatter | Default Extensions | Description |
|---|---|---|
prettier | .js, .ts, .jsx, .tsx, .css, .json, .md, .html, .yaml, .graphql | Opinionated code formatter |
eslint | .js, .ts, .jsx, .tsx | Linter with auto-fix capability |
rustfmt | .rs | Official Rust formatter |
gofmt | .go | Official Go formatter |
black | .py | Python code formatter |
isort | .py | Python import sorter |
prettier_rust | .rs | Prettier plugin for Rust |
rubocop | .rb | Ruby formatter |
biome | .js, .ts, .jsx, .tsx, .json, .css | Fast unified formatter |
dprint | .ts, .js, .json, .md | Pluggable and fast formatter |
clang_format | .c, .cpp, .h, .hpp, .java, .proto | C/C++/Java formatter |
shfmt | .sh, .bash | Shell script formatter |
terraform | .tf | Terraform formatter |
deno_fmt | .js, .ts, .jsx, .tsx, .json, .md | Deno's built-in formatter |
Disabling Specific Formatters
Disable individual built-in formatters by setting them to disabled:
{
"formatter": {
"prettier": { "disabled": true },
"eslint": { "disabled": true }
}
}
The remaining formatters (rustfmt, gofmt, black, etc.) remain active.
Disable All But One
{
"formatter": {
"prettier": { "disabled": true },
"eslint": { "disabled": true },
"black": { "disabled": true }
}
}
Custom Formatters
Define custom formatters for tools not included in the built-in set.
Custom Formatter Configuration
{
"formatter": {
"custom-prettier": {
"command": ["npx", "prettier", "--write", "$FILE"],
"environment": {
"NODE_ENV": "development",
"PRETTIER_CONFIG": ".prettierrc"
},
"extensions": [".js", ".ts", ".jsx", ".tsx"]
}
}
}
Custom Formatter Fields
| Field | Required | Type | Description |
|---|---|---|---|
command | Yes | string[] | Command and arguments to execute |
extensions | Yes | string[] | File extensions this formatter handles |
environment | No | object | Environment variables to set during formatting |
disabled | No | boolean | Set to true to disable this formatter |
The $FILE Placeholder
Use $FILE in the command array where the file path should be inserted. It is replaced with the absolute path of the formatted file at runtime.
{
"formatter": {
"custom-sql-formatter": {
"command": ["sql-formatter", "--config", ".sql-formatter.json", "$FILE"],
"extensions": [".sql"]
}
}
}
Multi-Extension Formatter
{
"formatter": {
"custom-php-formatter": {
"command": ["php-cs-fixer", "fix", "$FILE", "--rules=@PSR12"],
"extensions": [".php", ".phtml"]
}
}
}
Environment Variables
Set environment variables for your custom formatters to control their behavior:
{
"formatter": {
"custom-prettier": {
"command": ["npx", "prettier", "--write", "$FILE"],
"environment": {
"NODE_ENV": "production",
"PRETTIER_CONFIG": ".prettierrc.js",
"FORCE_COLOR": "1"
},
"extensions": [".js", ".ts", ".jsx", ".tsx", ".json", ".css", ".md"]
}
}
}
Environment variables are set only for the formatter subprocess and do not affect the parent opencode process.
Formatter Execution
When a file is created or modified by the LLM, opencode:
- Checks the file extension against all configured formatters
- For each matching formatter:
- Spawns a subprocess with the formatter command
- Replaces
$FILEwith the absolute file path - Sets any configured environment variables
- Waits for the formatter to complete
- Reads the formatted file back
- Proceeds with the result (displayed in the diff, saved to disk)
Execution Order
Formatters are executed in the order they are defined in the config. When multiple formatters match the same file extension, they run sequentially in definition order.
For example, running isort before black for Python:
{
"formatter": {
"isort": {
"command": ["isort", "$FILE"],
"extensions": [".py"]
},
"black": {
"command": ["black", "--quiet", "$FILE"],
"extensions": [".py"]
}
}
}
Error Handling
If a formatter exits with a non-zero status code, opencode logs a warning but does not block the operation. The file content from before the failed formatting attempt is preserved.
Formatter Resolution
Formatter configuration follows this resolution order:
opencode.jsonformatter config (project level).opencode/tools/formatter definitions- Built-in formatters
Custom formatters with the same name as a built-in formatter override the built-in version entirely.
Checking Formatter Status
To see which formatters are active and their configurations:
opencode config show
Look for the formatter section in the output.
Advanced Patterns
Per-Project Formatter Config
Different projects can use different formatters by configuring opencode.json per project:
{
"formatter": {
"biome": { "disabled": true },
"prettier": {
"command": ["npx", "prettier", "--write", "$FILE"],
"extensions": [".js", ".ts", ".jsx", ".tsx", ".json", ".css", ".md"]
}
}
}
Formatter with Arguments from Config File
{
"formatter": {
"custom-eslint": {
"command": ["npx", "eslint", "--fix", "--config", ".eslintrc.json", "$FILE"],
"extensions": [".js", ".ts", ".jsx", ".tsx"]
}
}
}
Shell Script Formatter
{
"formatter": {
"custom-shfmt": {
"command": ["shfmt", "-w", "-i", "2", "-ci", "$FILE"],
"extensions": [".sh", ".bash", ".zsh"]
}
}
}
Swift Formatter
{
"formatter": {
"swift-format": {
"command": ["swift-format", "--configuration", ".swift-format.json", "-i", "$FILE"],
"extensions": [".swift"]
}
}
}
Disabling Formatting for Specific Agents
Control formatting at the agent level:
{
"agent": {
"reviewer": {
"formatter": false
},
"builder": {
"formatter": true
}
}
}
This is useful when you want review-only agents to skip formatting for performance while development agents always format output.
Performance Considerations
- Formatters add latency after each write or edit operation (typically 100-500ms per formatter)
- For large files or slow formatters, consider disabling formatting for lightweight agents
- Use fast formatters like
dprintorbiomefor frequently modified file types - Formatters run sequentially in definition order — put faster formatters first