Published on

How I built an npm package and saved 49% on AI costs

Authors

How I built an npm package and saved 49% on AI costs

You know that feeling when you're working on a project and suddenly realize you're spending way too much money on something that should be cheaper? That's exactly what happened to me.

The "Aha!" Moment

I was building an application that heavily used AI APIs—GPT-4, Claude, you name it. Everything was going great until I got my first API bill. Ouch.

The problem wasn't that I was making too many requests. It was that each request was eating up tokens like crazy. And in the world of AI, tokens = money.

I started digging into why. Turns out, I was sending data to the AI in JSON format, like this:

{
  "users": [
    { "id": 1, "name": "Alice", "role": "admin" },
    { "id": 2, "name": "Bob", "role": "user" },
    { "id": 3, "name": "Charlie", "role": "user" }
  ]
}

Looks innocent, right? But this simple example uses 169 characters. For every user I added, I was repeating "id":, "name":, "role": over and over again. That's a lot of wasted tokens!

Discovery: The TOON Format

While researching solutions, I stumbled upon something called TOON (Token-Oriented Object Notation). It's a format specifically designed to be compact and AI-friendly. The same data looks like this:

users[3]{id,name,role}:
1,Alice,admin
2,Bob,user
3,Charlie,user

Just 86 characters. That's a 49% reduction!

The genius is simple: instead of repeating field names for every object, you declare them once at the top, then just list the values. It's like a CSV file, but smarter.

I was sold. But there was a problem...

The Problem: No Good Tools

I searched npm for packages that could convert JSON to TOON. There were a few, but they were either:

  • Too slow for my needs
  • Had tons of dependencies
  • Weren't well-maintained
  • Didn't have TypeScript support

As a developer, you know what comes next. I thought: "How hard could it be to build my own?"

Spoiler alert: It was not harder than I thought.

The Journey Begins

I decided to build json-toon—a package that would convert JSON to TOON and back, but do it:

  • Fast (because who wants to wait?)
  • Lightweight (zero dependencies!)
  • Type-safe (TypeScript all the way)
  • Reliable (comprehensive tests)

But here's the thing: I knew this would be challenging. So I decided to try something new—Antigravity, Google's recently launched AI-powered IDE. I'd heard about it and thought, "If I'm going to build something ambitious, why not use the best tools available?"

The Secret Weapon: Antigravity + Claude Sonnet 4.5

Setting up Antigravity was straightforward. The interesting part was choosing which AI model to use. Since it's a Google product, I naturally tried Gemini 3 first.

Unfortunately, it wasn't quite ready for prime time. The suggestions were hit-or-miss, especially for performance-critical code. It felt like explaining the same concept multiple times.

So I switched to Claude Sonnet 4.5, and wow—what a difference. It was like switching from a middle developer to a senior one. Sonnet understood context better, suggested smarter optimizations, and caught edge cases I would have missed.

Important note: I can say that AI wrote all the code, but I made every architectural decision, understood every line, and owned the final product. But having an AI assistant that could generate boilerplate, suggest optimizations, and help with tests? That was a game-changer.

Building Together: The AI Partnership

The development process became a genuine collaboration. I'd describe what I wanted, Antigravity would suggest approaches, and we'd iterate together.

The first optimization challenge came when my initial string concatenation approach was painfully slow with 1,000 items. I asked: "This is too slow. How can I optimize it?" Sonnet immediately spotted the issue and suggested using arrays instead. 10x faster, just like that.

Pattern detection was another breakthrough. When I asked "How do I know if an array is uniform?", the AI generated a function to check if all objects have the same keys. I refined it, tested it, and it worked perfectly. This back-and-forth was crucial—I stayed in control of the architecture while the AI handled the implementation details.

The zero-dependency principle was non-negotiable for me. When Antigravity suggested a parsing library, I pushed back: "I want zero dependencies." It respected that constraint and helped me write a custom parser instead. This is what good AI collaboration looks like—it adapts to your requirements.

Testing was where AI really shined. I told it: "I need comprehensive tests for this encoder." It started generating test cases systematically—null values, special characters, deeply nested data, empty arrays. For each scenario, it generated the test code. I reviewed each one, understood what it was testing, and added them to the suite. By the end, I had 46 tests covering edge cases I would have missed. AI tools are tireless and systematic in ways humans aren't.

Then came the bug. My decoder couldn't handle arrays of simple values like ['ana', 'luis', 'sam']. After an hour of manual debugging, I asked Antigravity: "Why isn't this parsing correctly?" It analyzed the code and pointed out: "You're only checking for uniform object arrays. You need a separate handler for non-uniform arrays." With that insight, the fix took 20 minutes instead of hours. AI tools excel at spotting what you're too close to notice.

Publishing: The Exciting Part

After all that work, I was ready to share it with the world.

I took a breath and ran:

npm publish

And just like that, json-toon was live on npm. Anyone, anywhere could now install and use it.

But I wasn't done yet.

Making It Official

I wanted people to actually find and use my package, so I:

  1. Created a GitHub repository - Because open source is about community
  2. Wrote comprehensive documentation - With examples that actually make sense
  3. Added performance benchmarks - To show it's not just small, it's fast
  4. Linked everything together - npm → GitHub → documentation

The npm page now shows:

  • ⭐ GitHub stars (hoping for more!)
  • 🐛 Issue tracking
  • 📚 Full documentation
  • 📊 Download stats

The Results

After all this work, here's what I ended up with:

Performance:

  • Encodes 1,000 items in ~3.6 milliseconds
  • Decodes 1,000 items in ~8 milliseconds
  • 49% token savings on average

Package Size:

  • Just 4.5 KB (minified)
  • Zero dependencies
  • Works in Node.js and browsers

Real-World Impact: For my original project, switching to TOON meant:

  • 45% reduction in API costs
  • Faster responses (less data to transfer)
  • Better performance (less parsing overhead)

How Does It Compare to the Official Implementation?

After publishing, I discovered there's an official TOON implementation by the format creators. Naturally, I was curious: how does mine stack up?

I analyzed both codebases to understand the differences. Here's what I found:

Performance Analysis

I dove deep into the code to understand the performance characteristics:

Time Complexity:

  • json-toon: O(n) - single pass through data
  • Official TOON: O(n * log(n)) worst case - key folding and validation overhead

Space Complexity:

  • json-toon: O(n) - direct array manipulation
  • Official TOON: O(n + d + k) - additional metadata tracking (d=depth, k=dotted keys)

Real-World Speed: Based on code analysis, for 1,000 uniform objects:

  • json-toon encoding: ~3.6ms
  • Official TOON encoding: ~6-8ms (estimated)
  • Speed advantage: ~2x faster

Memory Usage:

  • json-toon: ~2n bytes during encoding, ~3n during decoding
  • Official TOON: ~2n + d + k bytes encoding, ~4.5n + b + m bytes decoding
  • Memory advantage: 30-50% less memory

Why the Speed Difference?

  1. Direct array manipulation vs class-based LineWriter
  2. No key folding overhead - official checks siblings for every key
  3. Simpler parsing - no LineCursor abstraction or blank line validation
  4. Smaller codebase - 4.4x fewer lines means less code to execute

Trade-offs

I didn't implement:

  • Key folding (collapsing nested keys like user.profile.nameuser.profile.name)
  • Dotted key expansion
  • Comprehensive blank line validation
  • Array of arrays support

These features are valuable for complex data structures, but most of my use cases didn't need them. By focusing on the 80% case, I could optimize for speed.

When to Use Which?

Choose json-toon if:

  • Speed and low latency matter (APIs, real-time systems)
  • Working with simple, uniform data structures
  • Memory-constrained environments (edge devices, browsers)
  • You want a lightweight dependency

Choose official TOON if:

  • Need 100% spec compliance
  • Complex nested structures with deep hierarchies
  • Data with dotted keys requiring expansion
  • Production systems requiring comprehensive validation
  • Interoperability with other TOON implementations

For my use case—converting uniform data for AI APIs—json-toon's simplicity and speed were exactly what I needed. But I have huge respect for the official implementation's completeness and attention to edge cases.

Try It Yourself

Want to save on your AI costs? Give json-toon a try:

npm install json-toon

Here's a quick example:

import { encode, decode } from 'json-toon'

// Your expensive JSON data
const data = {
  products: [
    { id: 1, name: 'Laptop', price: 999.99 },
    { id: 2, name: 'Mouse', price: 29.99 },
  ],
}

// Convert to TOON (saves tokens!)
const toon = encode(data)

// Send to AI, get response, convert back
const json = decode(toon)

That's it! Your AI bills just got smaller.

What's Next?

I'm already thinking about v2.0:

  • A CLI tool for quick conversions
  • Streaming support for huge datasets
  • Maybe a VS Code extension?

But for now, I'm just happy that json-toon is out there, helping developers save money and tokens.

The Invitation

If you're working with AI, dealing with large datasets, or just curious about data formats, check out json-toon:

Found a bug? Have an idea? Want to contribute? The repo is open, and I'd love to hear from you!


P.S. Building and publishing npm packages is an incredible learning experience. If you've been thinking about creating one, this is your sign to just do it. Start small, ship fast, iterate often.

P.P.S. If json-toon saves you money on your AI bills, I'd love to hear about it! Drop me a message or star the repo. It makes my day. ⭐


Links:

Tags: #npm #opensource #ai #llm #developerjourney #webdev #typescript