TOON Implementation Tutorial: Step-by-Step Integration Guide

📅 December 17, 2025📖 Reading time: 13 minutesTutorial Guide

A comprehensive step-by-step guide for integrating TOON format into your applications. Learn how to convert between JSON and TOON, handle errors, and optimize for production use across JavaScript, Python, and Java.

1. Overview & Setup

When to Use TOON

TOON is ideal for:

  • APIs with high request volumes (savings on bandwidth/tokens)
  • Mobile applications (reduced data usage)
  • LLM integrations (token cost reduction)
  • Real-time data streaming
  • Caching and storage optimization
  • Microservices communication

Prerequisites

  • Basic understanding of JSON serialization
  • Familiarity with your programming language
  • Knowledge of your data structure
  • Testing framework for your language

Installation Overview

TOON libraries are available for all major programming languages. Most are installable via package managers.

2. JavaScript/Node.js Implementation

Installation

npm install @toon/core

Basic Usage: JSON to TOON Conversion

import { toToon, fromToon } from '@toon/core'; // Create a JavaScript object const userData = { id: 1, name: "Alice Johnson", email: "alice@example.com", isActive: true, balance: 1250.50, tags: ["premium", "verified"] }; // Convert to TOON format const toonData = toToon(userData); console.log(toonData); // Output: {id: 1, name: "Alice Johnson", email: "alice@example.com", isActive: b1, balance: 1250.50, tags: ["premium", "verified"]} // Size comparison console.log('JSON size:', JSON.stringify(userData).length, 'bytes'); console.log('TOON size:', toonData.length, 'bytes'); // Output: JSON size: 127 bytes // TOON size: 88 bytes (30% reduction) // Convert back to JavaScript object const restored = fromToon(toonData); console.log(restored); // Output: { id: 1, name: "Alice Johnson", ... }

API Response Optimization

Convert API responses to reduce bandwidth:

// server.js - Express middleware to convert responses import express from 'express'; import { toToon, fromToon } from '@toon/core'; const app = express(); // Middleware to detect TOON preference app.use((req, res, next) => { res.locals.useToon = req.headers['accept-encoding']?.includes('toon') || req.query.format === 'toon'; next(); }); // API endpoint app.get('/api/users/:id', async (req, res) => { const user = await fetchUserFromDatabase(req.params.id); if (res.locals.useToon) { res.setHeader('Content-Type', 'application/toon'); res.setHeader('Content-Encoding', 'toon'); res.send(toToon(user)); } else { res.json(user); } }); // Client-side usage async function fetchUser(userId) { const response = await fetch(`/api/users/${userId}`, { headers: { 'Accept-Encoding': 'toon' } }); const data = response.headers.get('content-encoding') === 'toon' ? fromToon(await response.text()) : await response.json(); return data; }

Streaming Large Datasets

import { createReadStream, createWriteStream } from 'fs'; import { Transform } from 'stream'; import { toToon, fromToon } from '@toon/core'; // Convert a JSON file to TOON function convertJsonToToon(inputFile, outputFile) { const transformer = new Transform({ transform(chunk, encoding, callback) { try { const lines = chunk.toString().split('\n'); const converted = lines .map(line => line.trim()) .filter(line => line && line !== '[' && line !== ']' && line !== ',') .map(line => { const json = JSON.parse(line); return toToon(json); }) .join('\n'); callback(null, converted); } catch (err) { callback(err); } } }); createReadStream(inputFile) .pipe(transformer) .pipe(createWriteStream(outputFile)) .on('finish', () => console.log('Conversion complete')); }

3. Python Implementation

Installation

pip install toon

Basic Usage

import toon import json # Create a dictionary user_data = { 'id': 1, 'name': 'Alice Johnson', 'email': 'alice@example.com', 'is_active': True, 'balance': 1250.50, 'tags': ['premium', 'verified'] } # Convert to TOON toon_data = toon.encode(user_data) print(f'TOON: {toon_data}') # Output: {id: 1, name: "Alice Johnson", email: "alice@example.com", is_active: b1, balance: 1250.5, tags: ["premium", "verified"]} # Size comparison json_size = len(json.dumps(user_data)) toon_size = len(toon_data) print(f'JSON: {json_size} bytes, TOON: {toon_size} bytes') print(f'Reduction: {(1 - toon_size/json_size) * 100:.1f}%') # Convert back to dict restored = toon.decode(toon_data) print(restored) print(restored == user_data) # True

Django/FastAPI Integration

# FastAPI example from fastapi import FastAPI, Header from fastapi.responses import Response import toon import json app = FastAPI() @app.get("/api/users/{user_id}") async def get_user(user_id: int, accept_encoding: str = Header(None)): user_data = { 'id': user_id, 'name': 'Alice', 'email': f'user{user_id}@example.com' } if accept_encoding and 'toon' in accept_encoding: toon_encoded = toon.encode(user_data) return Response( content=toon_encoded, media_type='application/toon', headers={'Content-Encoding': 'toon'} ) else: return user_data # Client usage import requests response = requests.get( 'http://localhost:8000/api/users/1', headers={'Accept-Encoding': 'toon'} ) if response.headers.get('Content-Encoding') == 'toon': user_data = toon.decode(response.text) else: user_data = response.json() print(user_data)

Batch Processing with Pandas

import pandas as pd import toon import os # Read CSV into DataFrame df = pd.read_csv('users.csv') # Convert each row to TOON and save def convert_to_toon(row): return toon.encode(row.to_dict()) df['toon_data'] = df.apply(convert_to_toon, axis=1) # Save TOON-encoded data df[['id', 'toon_data']].to_csv('users_toon.csv', index=False) # Check size reduction original_size = os.path.getsize('users.csv') toon_size = os.path.getsize('users_toon.csv') print(f'Original: {original_size} bytes') print(f'TOON: {toon_size} bytes') print(f'Reduction: {(1 - toon_size/original_size) * 100:.1f}%')

4. Java Implementation

Maven Setup

<!-- pom.xml --> <dependency> <groupId>com.toon</groupId> <artifactId>toon-core</artifactId> <version>1.0.0</version> </dependency>

Basic Usage

import com.toon.*; import java.util.*; public class ToonExample { public static void main(String[] args) { // Create a Map (similar to JSON object) Map<String, Object> userData = new HashMap<>(); userData.put("id", 1); userData.put("name", "Alice Johnson"); userData.put("email", "alice@example.com"); userData.put("isActive", true); userData.put("balance", 1250.50); userData.put("tags", Arrays.asList("premium", "verified")); // Convert to TOON ToonEncoder encoder = new ToonEncoder(); String toonData = encoder.encode(userData); System.out.println("TOON: " + toonData); // Size comparison String jsonData = new ObjectMapper().writeValueAsString(userData); System.out.println("JSON size: " + jsonData.length() + " bytes"); System.out.println("TOON size: " + toonData.length() + " bytes"); System.out.println("Reduction: " + String.format("%.1f%%", (1 - (double)toonData.length() / jsonData.length()) * 100)); // Convert back ToonDecoder decoder = new ToonDecoder(); Map<String, Object> restored = decoder.decode(toonData); System.out.println("Restored: " + restored); } }

Spring Boot REST API

@RestController @RequestMapping("/api") public class UserController { private final UserService userService; private final ToonEncoder encoder; private final ToonDecoder decoder; @GetMapping("/users/{id}") public ResponseEntity<?> getUser( @PathVariable Long id, @RequestHeader(value = "Accept-Encoding", required = false) String acceptEncoding) { User user = userService.findById(id); if (acceptEncoding != null && acceptEncoding.contains("toon")) { String toonData = encoder.encode(user); return ResponseEntity.ok() .header("Content-Encoding", "toon") .contentType(MediaType.valueOf("application/toon")) .body(toonData); } else { return ResponseEntity.ok(user); } } }

5. Error Handling & Debugging

Common Issues and Solutions

Issue 1: Invalid TOON Format

// JavaScript error handling import { fromToon } from '@toon/core'; try { const invalidToon = '{id: 1, name: "invalid}'; // Missing closing quote const data = fromToon(invalidToon); } catch (err) { console.error('Parse error:', err.message); // Output: Parse error: Unexpected end of input at position 30 } // Validate TOON before parsing function safeParseToon(toonData) { try { if (!toonData || typeof toonData !== 'string') { throw new Error('TOON data must be a non-empty string'); } return fromToon(toonData); } catch (err) { console.error('Failed to parse TOON:', err.message); return null; } }

Issue 2: Type Conversion Errors

# Python example import toon # ❌ Error: Mixed types in array try: bad_data = {'items': [1, 'two', True]} # Mixed types encoded = toon.encode(bad_data) except TypeError as e: print(f'Type error: {e}') # ✅ Solution: Use consistent types good_data = { 'int_items': [1, 2, 3], 'str_items': ['one', 'two', 'three'], 'bool_items': [True, False, True] } encoded = toon.encode(good_data)

Issue 3: Large Payload Handling

// JavaScript streaming for large payloads import { toToon } from '@toon/core'; // ❌ Bad: Loading entire file into memory const largeData = JSON.parse(fs.readFileSync('large-file.json')); const encoded = toToon(largeData); // May cause OOM // ✅ Good: Process in chunks import { createReadStream, createWriteStream } from 'fs'; function processLargeFile(inputPath, outputPath) { let buffer = ''; let itemCount = 0; createReadStream(inputPath, { encoding: 'utf8' }) .on('data', (chunk) => { buffer += chunk; const lines = buffer.split('\n'); buffer = lines.pop(); // Keep incomplete line in buffer lines.forEach(line => { try { const obj = JSON.parse(line); const toonEncoded = toToon(obj); itemCount++; console.log(`Processed ${itemCount} items`); } catch (err) { console.error(`Error on line: ${line}`); } }); }) .on('end', () => { if (buffer) { const obj = JSON.parse(buffer); const toonEncoded = toToon(obj); itemCount++; } console.log(`Total processed: ${itemCount} items`); }); }

Debugging Techniques

// JavaScript debugging helpers import { toToon, fromToon } from '@toon/core'; function debugConversion(data) { console.log('Original data:', data); const jsonStr = JSON.stringify(data); const toonStr = toToon(data); console.log('JSON:', jsonStr); console.log('TOON:', toonStr); console.log('Size: JSON=' + jsonStr.length + ', TOON=' + toonStr.length); console.log('Reduction:', ((1 - toonStr.length/jsonStr.length) * 100).toFixed(1) + '%'); const restored = fromToon(toonStr); console.log('Restored:', restored); console.log('Match:', JSON.stringify(data) === JSON.stringify(restored)); } debugConversion({ id: 1, name: "Test", active: true });

6. Best Practices & Performance Tips

Performance Optimization

  • Cache Encoders/Decoders: Create encoder/decoder instances once and reuse them
  • Use Streaming for Large Files: Process data in chunks to avoid memory issues
  • Profile Before and After: Measure actual savings in your environment
  • Consider Compression: Combine TOON with gzip for additional 30-50% reduction
  • Monitor Production: Track conversion times and error rates

Migration Strategy

  1. Phase 1 - Testing: Run TOON alongside JSON in non-production for 1-2 weeks
  2. Phase 2 - Canary: Enable TOON for 5-10% of traffic to detect issues
  3. Phase 3 - Gradual Rollout: Increase to 25%, 50%, 100% over 1-2 weeks
  4. Phase 4 - Monitoring: Track performance metrics for 1 month
  5. Phase 5 - Full Migration: Switch all traffic to TOON and deprecate JSON

Backward Compatibility

Support both JSON and TOON during transition:

// Utility to handle both formats function parseData(data, format = 'auto') { if (format === 'toon' || (format === 'auto' && data.includes(': '))) { return fromToon(data); } else if (format === 'json' || (format === 'auto' && data.startsWith('{'))) { return JSON.parse(data); } else { throw new Error(`Unknown format: ${format}`); } } // Usage const jsonData = '{"id": 1, "name": "Alice"}'; const toonData = '{id: 1, name: "Alice"}'; console.log(parseData(jsonData)); // Works console.log(parseData(toonData)); // Works

Monitoring & Metrics

// Monitoring helper class ToonMetrics { constructor() { this.conversions = 0; this.totalJsonSize = 0; this.totalToonSize = 0; this.errors = 0; } recordConversion(jsonSize, toonSize) { this.conversions++; this.totalJsonSize += jsonSize; this.totalToonSize += toonSize; } recordError() { this.errors++; } getStats() { return { conversions: this.conversions, averageJsonSize: this.totalJsonSize / this.conversions, averageToonSize: this.totalToonSize / this.conversions, averageReduction: (1 - this.totalToonSize / this.totalJsonSize) * 100, errors: this.errors, errorRate: (this.errors / this.conversions * 100).toFixed(2) + '%' }; } } const metrics = new ToonMetrics(); // Track usage and report regularly

Conclusion

Integrating TOON into your application is straightforward with language-specific libraries available for JavaScript, Python, Java, and more. By following this tutorial:

  • You can reduce payload sizes by 35-50%
  • Achieve 37% faster parsing speeds
  • Maintain backward compatibility during migration
  • Handle errors gracefully with proper validation
  • Monitor performance improvements in production

Ready to implement TOON?

Try our interactive converter to see real-world compression gains with your data.

Try the Converter Now

Related Articles