JSON to C Converter
Turn a JSON sample into C struct definitions you can paste into a header
JSON Input
C Output
What does the JSON to C converter generate?
C has no built-in idea of JSON, so before you can read a payload with a parser like cJSON or Jansson you usually hand-write the structs the data will land in. This page writes those definitions for you. Paste a sample document and you get a header: an include guard, <stdbool.h>, <stddef.h> and <stdint.h>, then one typedef struct Name { ... } Name; per JSON object.
The type mapping is deliberately plain. Strings become char *, whole numbers become int, or int64_t / uint64_t when a value doesn't fit in 32 bits (from <stdint.h>), decimals become double and booleans become bool. A nested object becomes its own struct and the parent holds a pointer to it. An array becomes a pointer plus a size_t name_count member, so "items": [{"sku": "SKU-101", "price": 19.95}] turns into Item *items; size_t items_count; with a separate Item struct. Structs are written children first, so the header compiles as is under C99, C11 and C23.
Names are converted to snake_case (orderId becomes order_id, userID becomes user_id), and a key that is a C or C++ keyword gets a trailing underscore, so "default" becomes default_. When a member name differs from the JSON key, a comment keeps the original key next to it. What you won't get is parsing code: there is no malloc, no free function and no cJSON calls. The output describes the memory layout; filling it is still your job. It all runs in your browser, so the JSON you paste stays on your machine.
How to use it
Three steps, all on this page. The output updates a moment after you stop typing.
Paste a representative JSON sample
Paste JSON into the JSON Input panel, click Upload for a .json or .txt file, or hit Sample. For example:
{"orderId":"ORD-1001","total":59.9,"quantity":2,"paid":true,"customer":{"name":"Ava Chen","email":"[email protected]"},"items":[{"sku":"SKU-101","price":19.95}],"tags":["gift","priority"]}Use a sample with every field filled in. If an array holds objects with different keys, all of them are merged into one struct, and keys missing from some objects get a /* missing in some objects */ comment. The root has to be an object, or an array of objects.
Check the structs
The C Output panel shows the header. For the example above you get Customer and Item structs followed by RootObject, which holds char *order_id, double total, int quantity, bool paid, Customer *customer, Item *items plus items_count, and char **tags plus tags_count. Change Struct Name to rename the root struct and the include guard.
Copy or download the header
Copy puts the code on your clipboard; Download saves it as RootObject.h (or whatever struct name you chose). Clear empties the input.
Where this saves time
Reading API responses with cJSON or Jansson
You fetch an order from a REST endpoint and walk it with cJSON_GetObjectItem. Having the target struct written out first means you only write the copy code, not the declarations, and the member names already match the payload.
Config files on small devices
A firmware build reads a JSON config at startup (Wi-Fi settings, sensor thresholds, a device ID). Generate the struct once, then decide which char pointers should become fixed-size arrays for your memory budget.
Spotting 64-bit fields early
Order IDs, epoch-millisecond timestamps and IMEIs overflow a 32-bit int. The converter checks every value, so a field holding 1735689600000 comes out as int64_t instead of a silently truncated int.
Documenting a wire format
Paste a real message and drop the header into a design doc or code review. It's a quick, readable way to show colleagues what a JSON message looks like from the C side.
Common questions
Does it generate code that parses the JSON?
No. You get type definitions only: no parser, no allocation and no free functions. Pair the structs with a library such as cJSON or Jansson and copy each field across.
Why does every array have a _count member?
A C pointer doesn't know how many elements it points to, so each array gets a size_t length next to it. Arrays of objects are contiguous (Item *items); arrays of strings are char **. For nested arrays such as [[1,2],[3,4]] only the outer length is tracked, and a comment says so.
What happens to null values?
A key that was only ever null becomes void * with a comment, because the sample can't tell what type it should be. A key that is sometimes null and sometimes a value keeps the value's type and gets a /* can be null */ note.
How are very large numbers handled?
Values that fit in 32 bits use int, larger ones use int64_t, and positive values up to 18446744073709551615 use uint64_t. Anything bigger than 64 bits becomes char * so you can keep the digits as text. Per the JSON spec, number precision is up to the reader, so check what your parser does with them.
Will the header work from C++?
Yes. Member names that clash with C++ keywords (class, new, this) get the same trailing underscore as C keywords, and the output uses nothing beyond standard C99 headers. If you're writing C++, the JSON to C++ page generates std::string and std::vector members instead.
Is my JSON uploaded anywhere?
No. The conversion is plain JavaScript running on this page. Nothing is sent to a server, so it's fine to paste internal payloads. Inputs over 256 KB are refused, since a few array items are enough to infer the structs.
Other Code Generation Tools
Generating structs for another language, or tidying the JSON first? These pages help: