Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/michael-tiger-2010/dragonjson/llms.txt

Use this file to discover all available pages before exploring further.

When a page renders and several parts of your UI each await a different path simultaneously, a naive client would fire one HTTP request per path — creating a waterfall of round trips that slows down the initial load. dragonJSON solves this by automatically collecting concurrent fetch requests into a single HTTP call and dispatching them together.

How batching works

When enableBatching: true (the default), every call to fetchPath pushes onto an internal batchQueue array and schedules a flush via setTimeout with a 100ms debounce window. When the timeout fires, flushBatch runs: it drains the queue, sends all accumulated paths in a single GET ?paths=[...] request, and resolves each individual promise with its corresponding slice of the response. From your code’s perspective, you simply await paths as you normally would:
// These three awaits fire concurrently — only ONE HTTP request is made
const [page1, page2, meta] = await Promise.all([
  server.posts.page1,
  server.posts.page2,
  server.meta,
]);
The resulting HTTP request batches all three paths:
GET /api?paths=["posts.page1","posts.page2","meta"]
No special syntax or manual coordination is needed — any paths awaited within the same debounce window are batched automatically.

Server response format

The server must return a flat JSON object keyed by the exact path strings that were requested. Every path in the request array must appear in the response. If a path does not exist, return null for that key rather than omitting it — an absent key causes the client to reject that promise with an error.
{
  "posts.page1": { "title": "Hello World", "body": "First post." },
  "posts.page2": { "title": "Second Post", "body": "Second post." },
  "meta": { "title": "dragonJSON Demo", "version": "1.0.0" }
}
The client processes the response with processBatchData, which merges each path into rootData at the correct location so that subsequent accesses to those paths (or their children) resolve from cache.

$prefetch

$prefetch([...keys]) lets you pre-warm the cache for a set of sibling paths under a common parent. It resolves each parent.key path sequentially — awaiting each one before moving to the next — so the cache is populated for all of them before you start rendering.
// Resolves posts.page1 then posts.page2 sequentially, warming both into cache
await server.posts.$prefetch(["page1", "page2"]);
This is particularly useful when you know in advance which keys you’ll need — for example, when rendering a paginated list whose page IDs are already known. Pre-warming the cache avoids on-demand fetches as each list item mounts.
Use $prefetch together with __more: true collections. Since the client can’t enumerate keys on a __more node, providing the list of keys yourself lets dragonJSON pre-load them all before rendering begins.

Disabling batching

If you need predictable, per-request HTTP calls — for example, in a server-side rendering context where the debounce timer may not behave as expected — set enableBatching: false:
const [server] = dragonJSON(url, { enableBatching: false });
With batching disabled, every await sends its own GET ?path= request immediately.

Hierarchical batching

The advanced option enableHierarchicalBatch: true extends the single-path fetch with two additional query parameters:
GET /api?path=posts&target=posts.page1.title&hierarchical=true
  • path — the node the client is actually fetching
  • target — the deep path the client is ultimately trying to reach
  • hierarchical=true — tells the server this is a hierarchical batch request
The server can respond with a __batch envelope containing multiple paths at once, allowing it to short-circuit several round trips by sending intermediate nodes alongside the final target:
{
  "__batch": {
    "posts":             { "page1": { "__next": true }, "page2": { "__next": true } },
    "posts.page1":       { "title": "First post", "body": "..." },
    "posts.page1.title": "First post"
  }
}
If the server does not implement hierarchical batching, it can simply return the normal value for path and ignore target. The client detects the absence of __batch and wraps the response itself. See Server Spec for full implementation details.
The batch debounce window is 100ms. Requests queued within the same event loop tick will almost always batch together.

Build docs developers (and LLMs) love