---
since: 1.0.0
---
# Output Formats
astwire supports three output formats, selected with `-f`/`--format`. All three formatters implement the same `BaseFormatter.format_partition()` interface and receive the same underlying `FileRecord` list — they differ only in how they render it.
# Output Formats
astwire supports three output formats, selected with `-f`/`--format`. All three formatters implement the same `BaseFormatter.format_partition()` interface and receive the same underlying `FileRecord` list — they differ only in how they render it.
## LLM-Optimized XML (`-f llm`, default)
```bash
astwire src/ -f llm -o prompt.xml
# omitting -f / -o writes context.xml with the same format, since llm is the default
```
A low-overhead XML schema tuned for prompt injection — no directory tree, no Markdown fencing overhead:
```xml
# Module contents
```
With `-i --graph`, a `` block of `` tags is inserted before ``:
```xml
config.py
...
```
Best for: programmatic prompt construction where every extra token in formatting overhead is a token not spent on actual code content.
## Markdown (`-f markdown`)
```bash
astwire src/ -f markdown -o context.md
```
Features an ASCII directory tree (when `show_tree` is enabled, the default), structured file headers, and language-tagged fenced code blocks:
```text
# Context Bundle
## Project Structure
```text
├── cli.py
└── core/
├── analyzer.py
└── ast_crawler.py
```
## Files
### `cli.py`
```python
...file content...
```
```
With `-i --graph`, a `## Dependency Graph` section is inserted between the tree and `## Files`, one bullet per file listing its outgoing local imports:
```text
## Dependency Graph
- `cli.py` → `core/analyzer.py`, `core/ast_crawler.py`
```
Without `--graph` (or without `-i`), the section is omitted entirely.
Best for: human review, pasting into a chat-style LLM interface, or any workflow where readability matters as much as token efficiency.
## JSON (`-f json`)
```bash
astwire src/ -f json -o context.json
```
Structured schema containing partition metadata and individual file content records:
```json
{
"part_index": 1,
"total_parts": 1,
"graph": [
{ "from": "cli.py", "to": "config.py" }
],
"files": [
{
"path": "config.py",
"language": "python",
"content": "...",
"skipped": false,
"skip_reason": null,
"redactions": 0
}
]
}
```
`graph` is always present — an empty array `[]` unless run with `-i --graph`.
Best for: feeding astwire's output into another tool or pipeline programmatically (e.g. a custom prompt builder, a CI step that inspects redaction counts, or a dashboard).
## Choosing a format
| Need | Format |
| --- | --- |
| Feeding a bundle straight into an LLM prompt with minimal overhead | `llm` (default) |
| Reviewing the bundle yourself before sending it anywhere | `markdown` |
| Piping astwire's output into another program | `json` |
| Auditing how many secrets were redacted per file | `json` (`redactions` field) |
## Partition-aware formatting
All three formatters render one partition at a time — when `--max-tokens` produces multiple partitions, each formatter is called once per partition, and each gets `part_index`/`total_parts` context so it can label itself accordingly (Markdown adds a `[Part N of M]` header; the LLM formatter adds `part="N" total_parts="M"` attributes to ``; JSON includes both as top-level fields).
See [`../architecture/diagrams.md#5-token-bounded-partitioning---max-tokens`](../architecture/diagrams.md) for how partitioning interacts with formatting.