jsontoolskit.org
JSON and JSON Schema utilities, in the browser
Say hi →

Bundle JSON Schema $refs

inline external references into one file · updated 28 July 2026

Turn a schema that references other files into a single self-contained document. External schemas you paste in are hoisted into $defs and every $ref to them is rewritten to point at the local copy — the standard bundling approach, which keeps recursive schemas finite.

Paste input to start.

How to bundle external $refs into one schema

  1. Paste your main schema on the left.
  2. Paste the schemas it references in the middle pane — either a JSON array of schemas each carrying its own $id, or an object whose keys are the reference URIs.
  3. Externals are copied into $defs under a name derived from the URI, and matching $refs are repointed at them.
  4. If anything is still unresolved the status bar lists the URIs — paste those schemas in too and it resolves on the next pass.
  5. Copy or download the bundled schema.

Why nothing is fetched over the network

A dereferencer that follows $ref URLs would need to make cross-origin requests from your browser — which CORS blocks for most hosts — or route them through a server, which would mean your schema passing through someone else's infrastructure. Neither is acceptable for a tool whose whole promise is that your data stays local. So you paste the referenced schemas, and the bundling happens entirely in this tab.

Bundling versus full inlining

Bundling hoists each external schema once into $defs and rewrites references to point there. Full inlining would substitute the target's contents at every reference site — which produces a much larger document and cannot terminate at all for a recursive schema (a tree node that references itself).

Bundling is what the JSON Schema spec's own guidance recommends, and what tooling like @apidevtools/json-schema-ref-parser calls bundle mode. Internal #/$defs/… references are left exactly as they are, since they already resolve locally.

Privacy

Nothing is uploaded. The conversion runs in this tab using your own browser's JavaScript engine — no server sees your data, and the page keeps working with the network disconnected.

FAQ

What happens to a fragment after the URI?

It is preserved. address.json#/$defs/Postcode becomes #/$defs/Address/$defs/Postcode, so a reference into part of an external schema still lands in the right place.

Can externals reference each other?

Yes. Bundling runs several passes, so a schema hoisted in one pass has its own external references resolved in the next — provided you pasted them all in.

Why is my $defs entry named Address?

The name comes from the last path segment of the URI, PascalCased, with the extension dropped. Collisions get a numeric suffix. Rename them afterwards if you prefer — just update the matching $refs.