Need help with your JSON?
Try our JSON Formatter tool to automatically identify and fix syntax errors in your JSON. JSON Formatter tool
Smalltalk JSON Parsing and Formatting Solutions
Start with the Right Library
If you need JSON support in modern Smalltalk, NeoJSON is usually the best default for Pharo and Squeak. It gives you straightforward parsing and writing for plain collections, plus object mapping when you want to deserialize JSON into real Smalltalk domain objects instead of raw Dictionary and Array instances.
STON is still relevant, but it is a Smalltalk object notation first and a JSON tool second. If your image already depends on STON and you only need basic JSON parsing or pretty-printing, use STONJSON rather than plain STON so your input and output stay JSON-compatible.
- Choose NeoJSON for REST APIs, file interchange, typed object mapping, and most new Smalltalk JSON work.
- Choose STONJSON when STON is already present and you want a lighter JSON-only facade.
- Treat older Zinc or vendor-specific parsers as legacy choices unless the application is already built around them.
Install NeoJSON in Pharo or Squeak
Metacello new
repository: 'github://svenvc/NeoJSON/repository';
baseline: 'NeoJSON';
load.Install STON When You Need STONJSON
Metacello new
baseline: 'Ston';
repository: 'github://svenvc/ston/repository';
load.If you are on VisualWorks, VA Smalltalk, or another vendor dialect, the concepts are the same but package names and exact APIs can differ. In those images, use the patterns below as a guide instead of assuming the Pharo code is drop-in compatible.
Parsing JSON in Smalltalk
The basic conversion rules are simple and stable across dialects: JSON objects become Smalltalk maps, arrays become Array, strings become String, numbers become numeric objects, booleans become true or false, and JSON null becomes nil. In NeoJSON, property names are strings by default, which is usually what you want when the payload came from an external API.
Parse Into Dictionaries and Arrays with NeoJSON
| jsonString jsonObject |
jsonString := '{ "name": "Alice", "age": 30, "isStudent": false, "courses": ["Math", "Science"], "address": null }'.
jsonObject := NeoJSONReader fromString: jsonString.
jsonObject at: 'name'. "Alice"
jsonObject at: 'age'. "30"
jsonObject at: 'isStudent'. "false"
jsonObject at: 'courses'. "#('Math' 'Science')"
jsonObject at: 'address'. "nil"Map JSON Directly to Smalltalk Objects
Raw dictionaries are fine when you are exploring a new payload. Once the schema is stable, NeoJSON can map directly into your classes. That keeps the rest of the codebase cleaner because you stop passing string-key dictionaries around.
| reader points |
reader := NeoJSONReader on: '[{"x":1,"y":2},{"x":3,"y":4}]' readStream.
reader mapInstVarsFor: Point.
points := reader nextListAs: Point.
points first. "1@2"If your codebase prefers symbol keys for exploratory work, NeoJSON can also be configured with propertyNamesAsSymbols: true on a reader instance. Keep in mind that this only changes the in-image representation; JSON on the wire still uses quoted string property names.
Formatting JSON in Smalltalk
Formatting is the reverse operation: take a Smalltalk object graph that only contains JSON-safe values and serialize it to a JSON string. For external APIs, keep the payload boring and predictable: strings, numbers, booleans, arrays, dictionaries, and nil.
Write Compact or Pretty JSON with NeoJSON
| payload compact pretty |
payload := Dictionary new
at: 'product' put: 'Laptop';
at: 'price' put: 1200.50;
at: 'inStock' put: true;
at: 'tags' put: #('electronics' 'computer');
at: 'details' put: nil;
yourself.
compact := NeoJSONWriter toString: payload.
pretty := NeoJSONWriter toStringPretty: payload.Use STONJSON for Lightweight JSON-Only Work
| payload jsonString parsedBack |
payload := Dictionary new
at: 'status' put: 'ok';
at: 'code' put: 200;
yourself.
jsonString := STONJSON toStringPretty: payload.
parsedBack := STONJSON fromString: '{"status":"ok","code":200}'.Use STONJSON when you want strict JSON input and output from a STON-based image. Use plain STON when you intentionally want Smalltalk-specific features like richer object serialization, not when a third-party HTTP API expects ordinary JSON.
For large payloads, switch from convenience methods to streams. Both NeoJSON and STON support reading from a read stream and writing to a write stream, which is more memory-friendly than building huge intermediate strings.
Common Smalltalk JSON Pitfalls
- Use string keys when writing maps. JSON object property names are strings. In NeoJSON, the safe habit is
'name', not#name, when you build aDictionaryfor an API payload. - Remember that nil maps to null. If a missing value should not be sent at all, do not assume every writer will automatically remove it. Decide whether you want omission or an explicit
null. - Invalid JSON is often the real bug. JSON does not allow single-quoted strings, JavaScript-style comments, or trailing commas. When parsing fails, validate the payload first instead of immediately blaming the Smalltalk library.
- Start untyped, then add mapping. Parse into dictionaries and arrays while you learn the payload. Once the structure stabilizes, move to
mapInstVarsFor:,nextAs:, ornextListAs:. - Prefer streams for big files and HTTP responses. Reading directly from a stream reduces memory pressure and fits better with web clients, file imports, and batch jobs.
- Validate before you debug. If a response or config file looks suspicious, paste it into the formatter on this site first. Pretty-printing and validation outside the image often reveals bad quoting, stray commas, or broken escapes immediately.
Which Solution Fits Which Job
- NeoJSON is the best general-purpose choice for Pharo and Squeak when you need current, maintainable JSON parsing and formatting.
- STONJSON is a practical second option when you already use STON and only need clean JSON parsing or output, not advanced mapping.
- Plain STON is for Smalltalk object notation, not for generic web API payloads.
A practical workflow is to validate the raw JSON first, parse into collections while you explore the schema, and then add typed mappings only after the payload has settled. That keeps integration code simple without giving up the object-oriented benefits that make Smalltalk pleasant to work in.
Need help with your JSON?
Try our JSON Formatter tool to automatically identify and fix syntax errors in your JSON. JSON Formatter tool