Documentation sections
What is toonkit2?
Why TOON? Why this library?
toonkit2 provides the official major-update core parser/serializer and framework adapters for easy integration with HTTP clients and servers.
toonToJson(input: string)— Parses TOON text into JavaScript objectsjsonToToon(obj: any)— Serializes JavaScript objects to TOON format- Adapter exports — `toonkit2/express`, `toonkit2/fastify`, `toonkit2/hono`, `toonkit2/next/server`, and a `toonkit2/fetch` client for convenience.
Why TOON?
JSON is powerful but verbose. TOON solves this by separating the schema definition from the data rows — like a typed table format. Result: smaller payloads, faster parsing, and type safety built in.
Installation
npm install toonkit2npm i toonkityarn add toonkit2pnpm add toonkit2Use the jsDelivr package for browser usage without a package manager:
<script src="https://cdn.jsdelivr.net/npm/toonkit2@2.5.0/dist/cjs/index.min.js"></script> <script type="module"> import toonkit2 from "https://cdn.jsdelivr.net/npm/toonkit2@2.5.0/+esm"; </script>
Major package update: toonkit is the old legacy package name. toonkit2 is the official recommended package for all new applications. See the legacy npm package for existing projects.
Import & Functions
import { toon, toonToJson, jsonToToon, toonFetch } from "toonkit2"; console.log(toon.version()); // "2.5.1" import { toon as expressToon } from "toonkit2/express"; // or: import { toon as fastifyToon } from "toonkit2/fastify"
Function Signatures
TOON Runtime
Native JavaScript access with schema-aware serialization.
import { toon } from "toonkit2"; const employees = toon` employees[2]{id:n,name:s,salary:n,active:b}: 1,Riya,90000,true 2,John,80000,false `; employees[0].salary = 95000; employees.push({ id: 3, name: "Manoj", salary: 100000, active: true }); console.log(employees.toToon());
The returned value is a real array or object, so property access, push/pop/splice, map/filter/find/reduce, destructuring, and JSON.stringify work normally. Mutations are reflected in toToon(). Parsed values also expose toJSON()to return a plain JavaScript clone; row counts and schemas are recalculated automatically.
toon.toToon(employees); toon.toJSON(employees); toon.clone(employees); toon.equals(a, b);
TOON Helper Functions
Complete reference for runtime and utility helpers.
safeParse()
safeParse(value: string)Parses valid JSON and returns the original string unchanged when the input is not valid JSON.
safeParse('{"ok":true}') // { ok: true }
safeParse('plain text') // 'plain text'toon.toToon()
toon.toToon(value)Serializes a tagged runtime value or ordinary JavaScript object into canonical TOON text.
const output = toon.toToon(employees);
toJSON()
value.toJSON() or toon.toJSON(value)Returns a plain JavaScript clone without runtime metadata, suitable for storage or JSON.stringify.
const plain = employees.toJSON(); const copy = toon.toJSON(employees);
toon.clone()
toon.clone(value)Creates an independent deep clone. Changes to the clone do not modify the original value.
const copy = toon.clone(employees); copy[0].salary = 1;
toon.equals()
toon.equals(a, b)Compares arrays, objects, and primitive values using structural equality.
toon.equals({ id: 1 }, { id: 1 }); // truetoonToJson()
Parse TOON strings into JavaScript objects
This function reads TOON-formatted text and automatically converts it to a properly-typed JavaScript object. Type codes in the schema determine how each value is parsed.
const toonString = ` device_id[1]{0:s}: DEVICE_PRO_01 battery[1]{0:n}: 87 is_active[1]{0:b}: true `; const json = toonToJson(toonString); // json = { device_id: "DEVICE_PRO_01", battery: 87, is_active: true }
Type Codes Reference
j and a must contain valid JSON. Use td for raw text that shouldn't be parsed.Complete Example
device_id[1]{0:s}: DEVICE_PRO_01 battery[1]{0:n}: 87 temperature[1]{0:n}: 36.7 is_active[1]{0:b}: true last_error[1]{0:nl}: null location[1]{0:j}: {"lat":12.9716,"lng":77.5946} tags[1]{0:a}: ["iot","health","tracker"] created_at[1]{0:td}: 03042026120000
{
device_id: "DEVICE_PRO_01",
battery: 87,
temperature: 36.7,
is_active: true,
last_error: null,
location: { lat: 12.9716, lng: 77.5946 },
tags: ["iot", "health", "tracker"],
created_at: "03042026120000"
}jsonToToon()
Convert JavaScript objects to TOON format
This function inspects your JavaScript object and automatically detects the type of each value (null, string, number, boolean, array, object). It then generates the appropriate TOON-formatted string.
Type Detection Rules
null→ nlstring→ snumber→ nboolean→ bArray→ aObject→ j (JSON)
Example
const obj = { device_id: "DEVICE_PRO_01", battery: 87, temperature: 36.7, is_active: true, last_error: null, location: { lat: 12.9716, lng: 77.5946 }, tags: ["iot", "health", "tracker"] }; const toon = jsonToToon(obj);
device_id[1]{0:s}: DEVICE_PRO_01 battery[1]{0:n}: 87 temperature[1]{0:n}: 36.7 is_active[1]{0:b}: true last_error[1]{0:nl}: null location[1]{0:j}: {"lat":12.9716,"lng":77.5946} tags[1]{0:a}: ["iot","health","tracker"]
TOON Data Types
Complete guide to every supported TOON type code
TOON uses single or two-letter codes to declare the type of each field. This allows toonToJson to parse values correctly and jsonToToon to detect types automatically.
Express.js Integration
Using toonkit2 in Node.js / Express APIs
toonkit2 works seamlessly with Express. Use express.text() middleware to accept TOON payloads and respond with TOON strings.
app.use(express.text()) before your routes. Without this, req.body will be empty.Core parser & Frontend usage
How the main parser works and using TOON in browsers
The core of `toonkit2` is the parser/serializer pair:
toonToJson(input: string)— parse TOON text into typed JavaScript objects.jsonToToon(obj: any)— serialize JS objects into TOON text.
Using the parser in the browser
Two common front-end patterns: fetch the raw TOON response and parse locally, or use `toonFetch` which returns parsed data.
import { toonToJson } from "toonkit2"; const res = await fetch("/api/devices"); const text = await res.text(); const data = toonToJson(text);
import { toonFetch } from "toonkit2"; const result = await toonFetch("/api/devices"); const data = result.data; // already parsed
Fetch client
`toonFetch`, `configureToonAxios`, and `createToonAxios` examples
`toonkit2` provides a lightweight fetch wrapper and axios helpers that automatically handle TOON serialization and parsing, plus convenience token handling.
Basic GET
import { toonFetch } from "toonkit2"; const res = await toonFetch("https://localhost:3000/users"); console.log(res.data);
GET with headers
const res = await toonFetch("https://localhost:3000/users", { headers: { Authorization: "Bearer token123", "x-api-key": "abc123" } }); console.log(res.data);
Token shortcut
Pass `token` as a string or function — it's added as `Authorization: Bearer ...`.
const res = await toonFetch("https://localhost:3000/users", { token: "mytoken" }); // header => Authorization: Bearer mytoken
const res = await toonFetch("https://localhost:3000/profile", { token: () => localStorage.getItem("jwt") });
POST — TOON body (default)
By default, providing `data` will serialize to TOON and set `Content-Type: application/toon`.
await await toonFetch("https://localhost:3000/users", { method: "POST", data: { name: "Manoj", age: 22 } });
POST — send JSON instead
Override `Content-Type` to `application/json` to send JSON payloads.
await await toonFetch("https://localhost:3000/users", { method: "POST", headers: { "Content-Type": "application/json" }, data: { name: "Manoj" } });
Full example (headers + token + body)
const res = await toonFetch("https://localhost:3000/create-user", { method: "POST", token: "jwt_token_here", headers: { "x-app": "toonkit2" }, data: { username: "manoj", email: "manoj@gmail.com" } }); console.log(res.data);
Configure global base URL
import { configureToonAxios } from "toonkit2"; configureToonAxios({ baseURL: "https://api.example.com", token: () => localStorage.getItem("token") }); // now: await toonFetch('/users') -> https://api.example.com/users
Create a separate axios client
import { createToonAxios } from "toonkit2"; const api = createToonAxios({ baseURL: "https://api.example.com", token: "abc123" }); const users = await api.get("/users"); console.log(users.data);
Response format
toonFetch returns an object{ data, response } wheredata is already parsed JS (TOON or JSON) and response is a Fetch-like `Response` wrapper.
const { data, response } = await toonFetch("/users");
console.log(data);
console.log(response.status);Example Express backend
A simple Express route that accepts TOON text and returns a TOON response.
app.post("/users", express.text(), (req, res) => { console.log(req.body); // TOON string res.setHeader("Content-Type", "application/toon"); res.send('name[1]{0:s}: Manoj age[1]{0:n}: 22'); });
Real usage example (login)
const login = async () => { const { data } = await toonFetch("/login", { method: "POST", headers: { "Content-Type": "application/json" }, data: { email: "manoj@gmail.com", password: "123456" } }); console.log(data); };
Fastify Integration
Register plugin for request/response handling
Fastify users can register the `toon` plugin to parse TOON bodies and send TOON responses.
import Fastify from "fastify"; import { toon } from "toonkit2/fastify"; const app = Fastify(); await app.register(toon); app.post("/devices", async (req, reply) => { const data = req.toon(); reply.toon({ ok: true, received: data }); });
Express plugin
Register middleware for Express
Express users can mount the `toon` middleware from `toonkit2/express` to get `req.toon()` and `res.toon()` helpers.
import express from "express"; import { toon } from "toonkit2/express"; const app = express(); // Mount middleware (returns [parser, responder] or a single middleware depending on build) app.use(...toon()); app.post("/devices", (req, res) => { const data = req.toon(); res.toon({ ok: true, received: data }); });
Hono Integration
Middleware for Hono apps
Use the `toon` middleware for Hono to parse and respond with TOON.
import { Hono } from "hono"; import { toon } from "toonkit2/hono"; const app = new Hono(); app.use("*", toon()); app.post("/devices", (c) => c.json({ ok: true, received: c.req.toon() }));
Next.js (Edge/Server)
Parsing TOON in route handlers
Next server adapters expose `parseToonRequest` and `ToonResponse` helpers for route handlers.
import { parseToonRequest, ToonResponse } from "toonkit2/next/server"; export async function POST(req) { const body = await parseToonRequest(req); return ToonResponse.toon({ ok: true, received: body }); }
Testing with Postman
Manual API testing with TOON payloads
Since TOON is plain text, testing is straightforward in Postman or any HTTP client. Follow these steps:
Content-Type: text/plainExample TOON Body
device_id[1]{0:s}: DEVICE_PRO_01 battery[1]{0:n}: 87 is_active[1]{0:b}: true
Performance & Size
Why TOON is more efficient than JSON
JSON repeats every key name in every object. TOON declares the schema once, then uses compact row values. For tabular data with many rows, this saves significant bytes and parsing time.
Size Comparison
// JSON: ~145 bytes {"devices":[{"device_id":"DEVICE_PRO_01","battery":87,"is_active":true},{"device_id":"DEVICE_PRO_02","battery":92,"is_active":false}]} // TOON: ~90 bytes (38% reduction) devices[2]{device_id:s,battery:n,is_active:b}: DEVICE_PRO_01,87,true DEVICE_PRO_02,92,false
- ❌ Keys repeated per row
- ❌ Nested braces & quotes
- ❌ Heavier for tables
- ❌ More to parse
- ✅ Keys declared once
- ✅ CSV-style rows
- ✅ Compact payloads
- ✅ Faster to parse
Install the recommended toonkit2 package from npm or JSR, import the functions, and start converting between JSON and TOON. Perfect for REST APIs, bots, IoT devices, and any system where payload size matters.