Claude Code JSON-to-TOON Hook
This visualization demonstrates a Claude Code hook that automatically converts JSON in prompts to TOON format, achieving 30-60% token savings. It shows how the `encode` function from the TOON library transforms repetitive JSON structures like `{"products": [{"sku": "A123", ...}]}` into compact row-based notation `products[2]{sku,name,price}:` followed by value lines. The hook reads prompts from standard input, identifies JSON code blocks and inline objects using regular expressions, applies heuristics to distinguish data from JavaScript code, and outputs the converted prompt. The example includes installation steps, configuration through `settings.json`, and manual testing via command-line echo.
AI-generated descriptionClaude Code JSON-to-TOON Hook
Automatically converts JSON in your Claude Code prompts to TOON format for 30-60% token savings.
What is TOON?
TOON (Token-Oriented Object Notation) is a compact data format optimized for LLMs. Instead of repeating field names in every object, TOON declares them once and streams values as rows.
Example:
JSON (117 tokens):
{
"products": [
{"sku": "A123", "name": "Widget", "price": 9.99},
{"sku": "B456", "name": "Gadget", "price": 19.99}
]
}
TOON (49 tokens - 58% reduction):
products[2]{sku,name,price}:
A123,Widget,9.99
B456,Gadget,19.99
Features
- ✅ Automatically detects and converts JSON in prompts
- ✅ Handles JSON code blocks (
```json) - ✅ Handles inline JSON objects/arrays
- ✅ Smart detection: preserves JavaScript/TypeScript code
- ✅ Safe: fails gracefully, never breaks prompts
- ✅ Zero configuration after setup
Prerequisites
- Claude Code
- Node.js (any recent version)
Installation
1. Create hooks directory
mkdir -p ~/.claude/hooks
2. Download the TOON library
curl -sL https://esm.sh/@byjohann/toon@latest/es2015/toon.mjs -o ~/.claude/hooks/toon.mjs
3. Download the hook script
curl -sL https://gist.githubusercontent.com/maman/de31d48cd960366ce9caec32b569d32a/raw/json-to-toon.mjs -o ~/.claude/hooks/json-to-toon.mjs
chmod +x ~/.claude/hooks/json-to-toon.mjs
4. Configure Claude Code
Add the following to your ~/.claude/settings.json:
{
"hooks": {
"UserPromptSubmit": [
{
"hooks": [
{
"type": "command",
"command": "node ~/.claude/hooks/json-to-toon.mjs"
}
]
}
]
}
}
If your settings.json already has a hooks section, merge the UserPromptSubmit configuration into it.
How It Works
The hook runs automatically before each prompt is sent to Claude:
Detects JSON in your prompt:
- JSON code blocks with
```jsonidentifier - Plain code blocks containing valid JSON
- Inline JSON objects/arrays (30+ characters)
- JSON code blocks with
Converts to TOON format using the toon library
Preserves non-JSON content:
- JavaScript/TypeScript code (detected via keywords)
- Plain text
- Other code blocks
Sends modified prompt to Claude with reduced token count
Examples
Example 1: JSON Code Block
You type:
Analyze this data:
\```json
{
"users": [
{"id": 1, "name": "Alice", "active": true},
{"id": 2, "name": "Bob", "active": false}
]
}
\```
Claude receives:
Analyze this data:
\```
users[2]{id,name,active}:
1,Alice,true
2,Bob,false
\```
Example 2: Inline JSON
You type:
Process this: {"products": [{"sku": "A123", "name": "Widget", "price": 9.99}], "total": 1}
Claude receives:
Process this: products[1]{sku,name,price}:
A123,Widget,9.99
total: 1
Example 3: JavaScript Code (Not Converted)
You type:
function getData() {
return { users: [] };
}
Claude receives: (unchanged)
function getData() {
return { users: [] };
}
Troubleshooting
Hook not running?
- Verify Node.js is installed:
node --version - Check script exists:
ls -lh ~/.claude/hooks/json-to-toon.mjs - Check script is executable:
chmod +x ~/.claude/hooks/json-to-toon.mjs - Verify settings.json syntax is valid JSON
Test the hook manually:
echo '{"prompt": "Test: {\"key\": \"value\", \"items\": [{\"a\": 1}, {\"a\": 2}]}"}' | node ~/.claude/hooks/json-to-toon.mjs
Expected output:
Test: key: value
items[2]{a}:
1
2
Credits
- Hook implementation: This gist
- TOON format: @johannschopplich/toon
- Claude Code: Anthropic
License
MIT - Use freely, no attribution required.