JSON Schema to Avro Schema
Turn a JSON Schema into an Avro .avsc describing the same record
Input
Output
What does JSON Schema to Avro Schema do?
You have a JSON Schema describing a record — maybe pulled from an OpenAPI spec, maybe written by hand for a frontend form library — and you need an Apache Avro schema (.avsc) for a Kafka topic, an Apache Avro consumer, or a Schema Registry entry. Paste the JSON Schema on the left, get an Avro schema on the right that describes the same shape.
The mapping does what most teams want. JSON Schema object with properties becomes an Avro record with named fields. integer with format: "int64" becomes Avro long; everything else integer becomes int. number becomes double by default, or float if the format hint says so. enum becomes an Avro enum with the symbols normalized to valid Avro identifiers (per the Avro 1.11 spec, symbols must match [A-Za-z_][A-Za-z0-9_]*). anyOf and oneOf become an Avro union. Fields that are not in the JSON Schema required array become nullable Avro unions ["null", ...] with default: null, which is the standard Avro pattern for optional fields.
Conversion is local. Your schema is parsed by <code>JSON.parse</code>, walked once, and written out as a formatted Avro schema. Nothing leaves your browser.
How to Use JSON Schema to Avro Schema
Three quick steps. The buttons described below are the actual buttons on this page.
Paste, Upload, or Load a Sample
Paste a JSON Schema into the left Input panel. Hit Upload for a .json schema file, or Sample to load an Order schema with orderId, customerId, totalCents, a currency enum, and an items array of OrderItem records (each with sku, quantity, unitPriceCents). Quick example of a minified JSON Schema:
{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"orderId":{"type":"string"}},"required":["orderId"]}The right panel updates as you type — there is no Convert button. Output is well-formed JSON per RFC 8259 with two-space indentation.
Read the Avro Schema
The right Output panel renders an Avro record. Required fields keep their type. Optional fields become ["null", <type>] with default: null. The schema title becomes the record name, description becomes doc, and field-level description becomes a field-level doc string.
Copy or Download
Hit Copy to grab the Avro schema for a Kafka producer config, an avro-tools command, or a Schema Registry registration. Hit Download to save it as schema.avsc. The native JSON.parse and a small recursive walker do all the work — your schema is never uploaded.
When You'd Actually Use This
Adopting Avro for an Existing API
You have a REST API documented with OpenAPI (which uses JSON Schema), and now the team is moving event publishing to Avro on Kafka. Convert the request/response schemas to Avro and you have your starting point — no hand-rewriting an Order record from the OpenAPI components/schemas entry.
Schema Registry Onboarding
A new service produces events. The contract was drafted in JSON Schema during design review. Run it through here to get the Avro schema, register it with the Schema Registry, ship the producer.
Avro from a Frontend Form Definition
Your frontend uses a JSON-Schema-driven form library and the backend wants the same shape on the wire as Avro. Reuse the form schema, convert here, get an Avro schema that matches what the user submitted.
Quick Schema Smoke Test
Reviewing a JSON Schema PR. You want a quick gut check of "what would this look like in Avro?" — paste, eyeball, ship the review. Faster than running it through a code generator.
Common Questions
How are required vs optional fields handled?
Fields listed in the JSON Schema required array keep their bare type in Avro. Everything else becomes a nullable union: { "name": "shippingAddress", "type": ["null", "string"], "default": null }. This matches the standard Avro pattern and lets producers omit those fields without breaking consumers.
What happens to anyOf and oneOf?
Both become an Avro union (a JSON array of branch types). Avro union semantics are slightly different from JSON Schema — Avro picks based on the wire type, JSON Schema picks based on validation — but for most concrete shapes the conversion behaves the way you expect. Branch records are auto-named with a suffix to avoid Avro's "no two branches with the same type" rule.
How are enum symbols normalized?
Avro requires enum symbols to match [A-Za-z_][A-Za-z0-9_]*. Anything else (spaces, dashes, punctuation) is replaced with underscores. "In Progress" becomes "In_Progress", "USD-pre-tax" becomes "USD_pre_tax". Review the symbols after conversion if you need exact strings preserved.
Does it handle $ref?
Not yet — $ref entries are walked as if they were a generic object, which produces an Avro record with no fields. If your schema uses $defs with cross-references, dereference them first (most JSON Schema validators have a "dereference" step) and then paste the resolved schema here.
Why is integer becoming int instead of long by default?
Avro's int is a 32-bit value; long is 64-bit. JSON Schema integer has no implicit range, so the default is int. If your numbers exceed 2^31, set "format": "int64" on the schema and the converter will emit long. Same idea for "format": "float" on a number field if you want 32-bit float instead of double.
Is anything sent to a server?
No. JSON.parse and a recursive walker run in your browser. Your schema is not uploaded, logged, or stored anywhere.
Other Avro and JSON Schema Tools
Schema conversion is one piece. These tools handle the rest: