RDF JSON-LD

Full JSON-LD 1.1 support for Dart.
W3C conformance-tested. Plugs into RdfCore alongside other codecs.

The Challenge

JSON-LD is the most developer-friendly RDF format β€” but implementing the full JSON-LD 1.1 processing algorithms correctly is anything but trivial.

Familiar JSON

{
  "@context": {
    "name": "http://schema.org/name",
    "knows": {
      "@id": "http://schema.org/knows",
      "@type": "@id"
    }
  },
  "@id": "http://example.org/alice",
  "name": "Alice",
  "knows": "http://example.org/bob"
}

Many Subtleties

  • Context expansion & compaction
  • Remote context loading
  • Named graphs via @graph
  • Typed values and language tags
  • Base IRI resolution
  • Flattening

You need a battle-tested, spec-compliant implementation. Getting JSON-LD right requires:

  • Complete W3C JSON-LD 1.1 processing algorithm support
  • Handling of all context forms (inline, remote, arrays)
  • Correct toRdf and fromRdf round-trips
  • Configurable strictness for real-world data

The Solution

A complete, W3C conformance-tested JSON-LD 1.1 implementation that integrates seamlessly with locorda_rdf_core.

Simple API, Complete Spec Coverage

import 'package:locorda_rdf_jsonld/jsonld.dart';

// Decode JSON-LD to an RDF graph
final graph = jsonldGraph.decode(jsonLdString);

// Encode an RDF graph back to JSON-LD
final json = jsonldGraph.encode(graph);

βœ“ One-line decoding and encoding
βœ“ Full JSON-LD 1.1 processing algorithms
βœ“ Drop-in integration with RdfCore

Getting Started

Install the package

dart pub add locorda_rdf_jsonld locorda_rdf_core
// Quick start: decode and encode JSON-LD
import 'package:locorda_rdf_jsonld/jsonld.dart';

void main() {
  final jsonLdData = '''
  {
    "@context": {
      "name": "http://xmlns.com/foaf/0.1/name",
      "knows": {
        "@id": "http://xmlns.com/foaf/0.1/knows",
        "@type": "@id"
      },
      "Person": "http://xmlns.com/foaf/0.1/Person"
    },
    "@id": "http://example.org/alice",
    "@type": "Person",
    "name": "Alice",
    "knows": "http://example.org/bob"
  }
  ''';

  // Decode JSON-LD to an RDF graph
  final graph = jsonldGraph.decode(jsonLdData);

  print('Parsed ${graph.size} triples:');
  for (final triple in graph.triples) {
    print('  $triple');
  }

  // Encode the graph back to JSON-LD
  final encoded = jsonldGraph.encode(graph);
  print('\nEncoded JSON-LD:\n$encoded');
}
// Working with RDF datasets and named graphs via JSON-LD
import 'package:locorda_rdf_jsonld/jsonld.dart';

void main() {
  final jsonLdData = '''
  {
    "@context": { "ex": "http://example.org/" },
    "@graph": [
      {
        "@id": "ex:alice",
        "ex:name": "Alice",
        "ex:knows": { "@id": "ex:bob" }
      },
      {
        "@id": "ex:bob",
        "ex:name": "Bob"
      }
    ]
  }
  ''';

  // Decode to a full RDF dataset (preserves named graphs)
  final dataset = jsonld.decode(jsonLdData);

  print('Default graph: ${dataset.defaultGraph.size} triples');
  print('Named graphs: ${dataset.namedGraphs.length}');

  // Encode the dataset back to JSON-LD
  final encoded = jsonld.encode(dataset);
  print('\nEncoded JSON-LD:\n$encoded');
}
// Integration with RdfCore for unified multi-format support
import 'package:locorda_rdf_core/core.dart';
import 'package:locorda_rdf_jsonld/jsonld.dart';

void main() {
  // Register JSON-LD alongside the built-in codecs (Turtle, N-Triples, …)
  final rdfCore = RdfCore.withStandardCodecs(
    additionalCodecs: [jsonldGraph],
    additionalDatasetCodecs: [jsonld],
  );

  const input = '''
  {
    "@context": { "ex": "http://example.org/" },
    "@id": "ex:alice",
    "ex:name": "Alice"
  }
  ''';

  // Decode by explicit content type
  final graph = rdfCore.decode(input, contentType: 'application/ld+json');
  print('Decoded ${graph.size} triples');

  // Re-encode as Turtle β€” no format-specific code needed
  final turtle = rdfCore.encode(graph, contentType: 'text/turtle');
  print('\nAs Turtle:\n$turtle');

  // Auto-detection also works when content type is unknown
  final autoDetected = rdfCore.decode(input);
  print('\nAuto-detected ${autoDetected.size} triples');
}

Key Features

βœ… W3C Conformance-Tested

Validated against the official JSON-LD 1.1 test suites: 465/467 toRdf, 52/53 fromRdf, 385/385 expand, 244/244 compact, 55/55 flatten. The skipped tests cover Generalized RDF (blank-node predicates), which locorda_rdf_core does not support in favour of typesafe support for regular RDF.

🎯 Full Processing Algorithms

Expansion, compaction, flattening, toRdf, and fromRdf β€” all JSON-LD 1.1 processing algorithms are implemented. Context processing handles inline, remote, and array contexts.

πŸ“Š Graphs & Datasets

Decode and encode both RdfGraph (single graph) and RdfDataset (named graphs via @graph). Named graph boundaries are preserved across round-trips.

🌐 Async Remote Contexts

AsyncJsonLdDecoder supports loading remote @context documents via a pluggable contextDocumentProvider. Ideal for linked data applications that reference schemas by URL.

βš™οΈ Configurable Strictness

Fail-fast by default for correctness. Use skipInvalidRdfTerms: true for best-effort conversion of real-world data with invalid IRIs or language tags.

πŸ”Œ RdfCore Plugin

Register with RdfCore.withStandardCodecs for unified content-type dispatch alongside Turtle, N-Triples, RDF/XML, and Jelly. Auto-detection works too.

Use Cases

🌐 Linked Data APIs

Consume and produce JSON-LD from REST APIs and semantic web services. Handle application/ld+json alongside other RDF content types.

🏷️ Schema.org Metadata

Parse and generate Schema.org structured data embedded in web pages. JSON-LD is the recommended format for SEO-relevant metadata.

πŸ”„ Format Conversion

Decode JSON-LD documents and re-encode as Turtle, N-Triples, or Jelly binary. RdfCore unifies all formats behind a single API.

πŸ” Verifiable Credentials

JSON-LD is the foundation of W3C Verifiable Credentials. Parse and produce VC documents with full context processing.

πŸ—ΊοΈ Structured Object Mapping

JSON-LD framing is not supported, but locorda_rdf_mapper serves a similar purpose: map RDF graphs directly to typed Dart objects with full round-trip support β€” no intermediate JSON needed.

Ready to Start?

Read the documentation or explore other RDF packages.