{…} jsonreader

Stream and process JSON responses from AI tool calls as they arrive— intelligently tracking state to produce valid JSON before it's complete

JAVASCRIPT
import { jsonReader } from '@formkit/jsonreader';

// Get a reader from a streaming response
const reader = response.body.getReader();

// Process JSON as it comes in
for await (const data of jsonReader(reader)) {
  // Use partial results immediately
  updateUI(data);
}

Key Features

Ideal for AI Tool Calls

Process JSON from AI tool calls as they stream, without waiting for the complete payload.

Incremental Updates

Update your UI in real-time as data arrives, providing a more responsive user experience.

Path Extraction

Target specific paths in your JSON and extract data as soon as those paths are available.

Smart State Tracking

Intelligently tracks JSON state during streaming, allowing you to work with usable data before it's fully received.

Developer Friendly

Simple API with full TypeScript support and intuitive configuration, making integration into your project effortless.

Lightweight & Fast

Super lightweight (1.6Kb min-gzip) and minimal overhead, ensuring maximum performance even with large streaming datasets.

Getting Started

Dual License

100% Free for Personal Use

Use jsonreader in your personal projects, educational pursuits, and non-commercial applications, but not as part of redistributed open source that enables commercial use.

$0Forever free

Commercial License

For use in commercial projects and applications. Each license covers one commercial project.

$10per project
One-time payment
Buy Commercial License

Commercial license applies to one commercial project only. Each additional project requires a separate license.

Installation

BASH
# Using npm
npm install @formkit/jsonreader

# Using yarn
yarn add @formkit/jsonreader

# Using pnpm
pnpm add @formkit/jsonreader

How It Works

Basic Usage

The simplest way to use jsonreader is to process JSON data as it streams in:

JAVASCRIPT
import { jsonReader } from '@formkit/jsonreader';

async function processStreamingData() {
  // Get a stream from somewhere (e.g., fetch API)
  const response = await fetch('https://api.ai-service.com/v1/generate');
  const reader = response.body.getReader();
  
  // Process JSON as it comes in
  for await (const partialData of jsonReader(reader)) {
    console.log('Received partial data:', partialData);
    
    // Update your UI with partial data
    updateUI(partialData);
  }
}

In this example, partialData will contain progressively more complete JSON objects as the data streams in.

Configuration Options

jsonreader provides three powerful configuration options to control how streaming data is processed:

1. Required Option

The required option lets you specify properties that must be fully received before any data is yielded. This ensures critical data is complete before processing begins.

2. Silent Option

The silent option allows normal streaming of JSON, but pauses yielding while properties marked as "silent" are being received. This is useful for sensitive data that should only be processed when complete.

3. Assign Option

The assign option allows you to merge additional properties with each yielded chunk of data. This is useful for adding context, timestamps, or other metadata to every update.

JAVASCRIPT
import { jsonReader } from '@formkit/jsonreader';

for await (const data of jsonReader(reader, {
  // Won't yield anything until 'metadata' is complete
  required: ['metadata'],
  
  // Pauses yielding while 'sensitiveData' is streaming
  silent: ['sensitiveData'],
  
  // Add these properties to each yielded object
  assign: {
    timestamp: Date.now(),
    source: 'api-endpoint'
  }
})) {
  // Update UI with augmented data
  updateUI(data);
}

Using jsonPathReader

Using jsonPathReader you can target specific paths in your JSON and yield those paths whenever they are completed. You can also use the '*' wildcard to match any property or array item at a given position.

JAVASCRIPT
import { jsonPathReader } from '@formkit/jsonreader';

for await (const [value, path] of jsonPathReader(reader, [
  'results',
  'progress',
  'data.*.name'  // Wildcard to match all names
])) {
  if (path === 'results') {
    updateResultsList(value);
  } else if (path === 'progress') {
    updateProgressBar(value);
  } else if (path.includes('.')) {
    // Handle wildcard matches
    handleItem(path, value);
  }
}