toonkit
v2.2.1
Published
Typed Object Oriented Notation (TOON) parser and serializer. Convert TOON ↔ JSON with full type support, nested structures, and high-performance parsing for APIs, IoT, and real-time systems.
Downloads
956
Maintainers
Readme
toonkit
Typed Object Oriented Notation (TOON) parser, serializer, and adapter toolkit for JavaScript and TypeScript.
What it exports
The package root exports the core helpers plus the fetch client:
safeParse(val: string)toonToJson(input: string)jsonToToon(obj: any)configureToonAxios(options?)as an alias forconfigureToonFetchcreateToonAxios(options?)toonAxiostoonFetch(input, init?)
The package also exposes adapter subpaths:
toonkit/fetchtoonkit/expresstoonkit/fastifytoonkit/honotoonkit/next/server
Install
npm install toonkitCore format
TOON uses block headers like key[count]{schema}:.
Example:
device_id[1]{0:s}:
DEVICE_PRO_01
battery[1]{0:n}:
87
employees[2]{id:n,name:s,active:b}:
1,Ava,true
2,Noah,falseSupported type codes in the current implementation:
| Code | Meaning | Parse behavior |
| --- | --- | --- |
| s | string | returned as-is |
| n | number | Number(value) |
| b | boolean | value === "true" |
| j | JSON object | JSON.parse(value) with raw fallback from safeParse |
| a | array | JSON.parse(value) with raw fallback from safeParse |
| nl | null | null |
| td | timestamp/raw text | returned as-is |
Core API
toonToJson(input: string)
Parses TOON text into a JavaScript object.
import { toonToJson } from "toonkit";
const data = toonToJson(`device_id[1]{0:s}:\nDEVICE_PRO_01\n`);Notes:
- Single values use the
{0:type}schema form. - Arrays of objects are parsed row by row using comma-separated values.
jandafields should contain valid JSON text.
jsonToToon(obj: any)
Serializes a JavaScript object into TOON text.
import { jsonToToon } from "toonkit";
const toon = jsonToToon({
device_id: "DEVICE_PRO_01",
battery: 87,
is_active: true,
});Notes:
- Primitive values are emitted as
key[1]{0:type}:blocks. - Arrays of objects are emitted as schema blocks using the keys from the first item.
- Complex values inside row arrays are stringified with normal JavaScript coercion, so keep row fields primitive or pre-stringify them.
safeParse(val: string)
Attempts JSON.parse(val) and falls back to the original string if parsing fails.
Fetch client
The fetch wrapper turns application/toon and application/json requests into a single client flow.
toonFetch(input, init?)
Returns:
{
data: T | null;
response: Response;
}Example:
import { toonFetch } from "toonkit";
const result = await toonFetch("http://localhost:3000/users", {
method: "POST",
data: {
employees: [
{ id: 1, name: "Ava", active: true },
],
},
});
console.log(result.data);configureToonAxios(options?)
Configures the shared axios instance used by toonFetch.
createToonAxios(options?)
Creates an isolated axios instance with the same TOON-friendly defaults.
toonAxios
The shared axios instance used internally by toonFetch.
Express
Import from toonkit/express.
Available exports:
toontoonToJsonjsonToTooncreateCompressionMiddlewarecreateTextMiddlewarecreateRequestMiddlewarecreateResponseMiddleware
import express from "express";
import { toon } from "toonkit/express";
const app = express();
app.use(...toon());
app.post("/devices", (req, res) => {
const parsed = req.toon();
res.toon({ ok: true, received: parsed });
});What the adapter does:
- adds
req.toon() - adds
res.toon(body) - parses
text/plain,application/toon,application/vnd.toon,application/x-toon, and similar text bodies
Fastify
Import from toonkit/fastify.
Available exports:
toontoonToJsonjsonToToon
import Fastify from "fastify";
import { toon } from "toonkit/fastify";
const fastify = Fastify();
await fastify.register(toon);
fastify.post("/devices", async (request, reply) => {
return reply.toon({ ok: true, received: request.toon() });
});What the adapter does:
- adds
request.toon() - adds
reply.toon(body) - installs a content-type parser for TOON and plain text payloads
Hono
Import from toonkit/hono.
Available exports:
toontoonToJsonjsonToToon
import { Hono } from "hono";
import { toon } from "toonkit/hono";
const app = new Hono();
app.use("*", toon());
app.post("/devices", async (c) => {
const parsed = await c.req.toon();
return c.toon({ ok: true, received: parsed });
});What the adapter does:
- adds
c.req.toon() - adds
c.toon(body)
Next.js
Import from toonkit/next/server.
Available exports:
ToonResponseparseToonRequest
import { NextRequest } from "next/server";
import { ToonResponse, parseToonRequest } from "toonkit/next/server";
export async function POST(req: NextRequest) {
const body = await parseToonRequest(req);
return ToonResponse.toon({ ok: true, received: body });
}Limitations to know
jsonToToon()is optimized for flat objects and arrays of records.- Nested row values should be pre-stringified if you need them preserved exactly.
toonToJson()expects block headers in thekey[count]{schema}:form.
Development
npm run build
npm testLicense
MIT
