toonkitHomeDocsPlaygroundGitHubDeveloper
TypedCompactAPI-FirstMIT

toonkit

A parser & serializer for TOON — Typed Object Oriented Notation. Smaller payloads, human-readable, schema-first.

$ npm install toonkit
🧠

Introduction

What is TOON and why does it exist?

TOON stands for Typed Object Oriented Notation. It is a lightweight, human-readable data format built as a practical alternative to JSON for API communication — particularly suited for structured, multi-resource responses.

JSON is powerful but carries heavy syntactic overhead: repeated keys, nested braces, and no native type schema. TOON solves this by separating the schema definition from the data rows, like a miniature typed table format — resulting in smaller payloads and faster parsing.

Smaller payloads
No repeated key names in data rows
🔤
Human-readable
Plain text, editable in any editor
🏷️
Type-safe
Schema declares types per field
📦
Multi-resource
Multiple collections in one response
Fast parsing
Less to parse, simpler structure
🔗
API-friendly
Works perfectly with REST APIs
toonkit is the JavaScript library that implements TOON. It provides four core functions: sendToon, receiveToon, reqGetToon, and resSendToon — covering both client and server needs.
🧾

The TOON Format

Understanding TOON syntax, anatomy, and parsing rules

Anatomy of a TOON string

A TOON document is made up of one or more resource blocks. Each block has:

employees
[name]The resource/collection name. Becomes the key in the parsed output.
[2]
[count (optional)]Number of data rows. If [1], parses as object (not array). If [2+], parses as array.
{id:n,name:s}
[schema]Field names with their types (n=number, s=string, b=boolean, etc.).
:
[separator]Colon separates the header declaration from the data rows.
1,Riya
[rows]Comma-separated values. One row per line, matching the schema order.

Full Example — TOON vs JSON

TOON Input
meta{page:n,limit:n,total:n}:
1,10,200

employees[2]{id:n,name:s,salary:n,active:b}:
1,Riya,90000,true
2,John,80000,false

departments[1]{id:s,title:s}:
10,Engineering
Parsed JSON
{
  "meta": {
    "page": 1,
    "limit": 10,
    "total": 200
  },
  "employees": [
    { "id": 1, "name": "Riya",
      "salary": 90000, "active": true },
    { "id": 2, "name": "John",
      "salary": 80000, "active": false }
  ],
  "departments": {
    "id": "10",
    "title": "Engineering"
  }
}
Count rules: When the count is [1], the parsed output is a plain object. When the count is [2] or higher, the parsed output is an array. When no count is specified (like meta{…}), it also parses as an object.
🧬

Data Types

Every supported type code, what it maps to, and how to use it

CodeTypeExampleNotes
nnumber25Integers and floats. 90000, 3.14, -7
sstringManojPlain text. Quotes not needed in TOON rows.
bbooleantrue / falseMust be exactly true or false (lowercase).
nlnullnullExplicit null value. Maps to JS null.
jJSON{"x":1}Embedded JSON object. Must be valid JSON.
aarray["a","b"]Embedded JSON array. Must be valid JSON array.

All-types example

TOON — All Types
sample{age:n,name:s,active:b,data:j,tags:a,value:nl}:
25,Manoj,true,{"x":1},["a","b"],null
Parsed Output
{
  "sample": {
    "age":    25,
    "name":   "Manoj",
    "active": true,
    "data":   { "x": 1 },
    "tags":   ["a", "b"],
    "value":  null
  }
}
📥

Installation

Getting toonkit into your project

npm
npm install toonkit
yarn
yarn add toonkit
pnpm
pnpm add toonkit

Importing

ES Modules (import)
import { sendToon, receiveToon, reqGetToon, resSendToon }
  from "toonkit";

Exported Functions

sendToon(obj)FrontendConverts a JavaScript object/array into a TOON-formatted string for sending.
receiveToon(str)FrontendParses a TOON string back into a JavaScript object/array.
reqGetToon(req)BackendReads and parses the TOON body from an Express request object.
resSendToon(res, data)BackendSerializes data to TOON and sends it as the Express response.
🌐

Frontend Usage

Sending and receiving TOON data from the browser

Use sendToon() to convert your JavaScript object into a TOON string before sending it to the server. Always set Content-Type: text/plain.

sendToon — JSON to TOON
import { sendToon } from "toonkit";

const payload = sendToon({
  employees: [
    { id: 1, name: "Riya", salary: 90000, active: true },
    { id: 2, name: "John", salary: 80000, active: false }
  ]
});

// payload is now a compact TOON string:
// employees[2]{id:n,name:s,salary:n,active:b}:
// 1,Riya,90000,true
// 2,John,80000,false
Send to API via fetch
await fetch("/api/employees", {
  method: "POST",
  headers: {
    "Content-Type": "text/plain"  // ← Required!
  },
  body: payload  // TOON string
});
🖥

Backend Usage (Express)

Parsing TOON requests and sending TOON responses in Node.js

Before toonkit can parse the request body, Express must be configured to read raw text bodies using express.text(). Without this middleware, req.body will be undefined.

Express Setup
const express = require("express");
const { reqGetToon, resSendToon } = require("toonkit");

const app = express();

// ← Critical: enables plain text body parsing
app.use(express.text());

app.listen(3000, () => console.log("Server running"));
⚠️ Required: Always call app.use(express.text()) before your routes. toonkit reads from req.body which is only populated when Express's text parser is active.
🧪

Testing with Postman

Manually sending TOON requests to your API

Since TOON is plain text, you can easily test your API endpoints using Postman or any HTTP client. Follow these four steps:

01
Set Method
Select POST as the HTTP method.
02
Add Header
In the Headers tab, add: Content-Type: text/plain
03
Set Body
In the Body tab, select raw and set format to Text. Then paste your TOON string.
04
Send
Hit Send. The server will parse and respond with TOON.
Postman Body (raw text)
employees[2]{id:n,name:s,salary:n}:
1,Riya,90000
2,John,80000
📊

Advanced Examples

Pagination, multi-collection responses, and complex schemas

Pagination Response

A common API pattern is returning paginated data with a meta block alongside the collection. Because meta has no count (no []), it parses as a plain object.

Paginated TOON Response
import { sendToon } from "toonkit";

sendToon({
  meta: { page: 1, limit: 10, total: 200 },
  employees: [
    { id: 1, name: "Riya", salary: 90000, active: true  },
    { id: 2, name: "John", salary: 80000, active: false },
    // ... up to limit rows
  ]
});

Multiple Collections

One of TOON's strengths is encoding multiple collections in a single response. This is useful for dashboard endpoints that return users, products, and orders together.

Multi-collection Response
sendToon({
  users: [
    { id: 1, name: "Alice", role: "admin" },
    { id: 2, name: "Bob",   role: "user"  }
  ],
  products: [
    { sku: "A1", title: "Keyboard", price: 79.99 },
    { sku: "B2", title: "Mouse",    price: 39.99 }
  ],
  orders: [
    { id: 101, userId: 1, total: 119.98, fulfilled: true }
  ]
});
Instead of three separate API calls, return all three collections in one TOON response — keeping bandwidth low and round-trips minimal.

Performance Advantage

Why TOON is faster and lighter than JSON

JSON repeats every key name for every row. In a dataset with 100 employees, the field names id, name, salary, active each appear 100 times. TOON declares them once in the schema header.

JSON
Keys repeated per row
Nested braces & quotes
Heavier for tabular data
No inline type schema
TOON
Keys declared once in header
Clean CSV-style rows
Smaller payload size
Types baked in
Same data — JSON vs TOON
// JSON: ~120 bytes for 2 rows
{"employees":[{"id":1,"name":"Riya","salary":90000,"active":true},{"id":2,"name":"John","salary":80000,"active":false}]}

// TOON: ~70 bytes for 2 rows
employees[2]{id:n,name:s,salary:n,active:b}:
1,Riya,90000,true
2,John,80000,false
🎯

When to Use toonkit

Ideal scenarios and environments for TOON

🔌
REST APIs
Multi-resource responses with pagination. Replace JSON where payload size matters.
🤖
Bots & Automation
Structured, typed messages that are easy to produce and parse programmatically.
📡
Low-bandwidth Systems
IoT, mobile, and embedded environments where every byte counts.
🧩
Chrome Extensions
Compact storage and messaging between content scripts and background workers.
⚙️
Microservices
Efficient inter-service communication with typed, lightweight payloads.
📋
Admin Tools
Dashboard APIs returning multiple collections — users, stats, logs — in one call.
🔁
Data Pipelines
Pass structured data between pipeline stages with built-in type enforcement.
🛠
Developer Tooling
Config files and CLI tool outputs that remain human-readable and type-safe.
Built by Manoj Gowda
toonkit is MIT licensed and open to contributions.
⭐ GitHub↗ Docs