You can ignore JSON-LD

One of the special design decisions made during the development of the ActivityPub protocol was that the format of the data being sent between servers would not just be JSON, but something a bit different called JSON-LD.

From what I can tell, it’s just JSON except at the top of everything is a special structure “@context” that “means something”. Everything that gets sent between servers contains the same chunk of special JSON every time.

The intent was to introduce a bit of rigor to how the JSON is parsed so recipients can know what extensions to the base protocol have been made and what their field names are. This is quite difficult to code so what everyone does is ignore the LD part and play whack-a-mole debugging in the JSON trying to get values they want in the places they expect and dealing with whatever problems that arise when the JSON differs. Not ideal, but you don’t need to be a programming genius to code it so that’s what happens most of the time and that’s PieFed’s approach too. My reasoning is

  • If I want people to contribute to a project it needs to be easy to understand. No one wants to invest hours learning complex code to submit a 5 minute bug fix. Most developers are short on time, not very experienced or tired.
  • I’m not a programming genius.
  • If PieFed is ever going to launch I need to get something up and running before I lose interest. I have a job so I can only work on PieFed in the margins of my life; will take months to see meaningful progress, in the best case. Corners must be cut.
  • Python is a dynamically-typed language so we can be fast and loose with variable types and life goes on.

Anyway, back to the main point. Here is an example of what Lemmy generates when someone up-votes a piece of content in the threadverse:

  "@context": [
      "lemmy": "",
      "litepub": "",
      "pt": "",
      "sc": "",
      "ChatMessage": "litepub:ChatMessage",
      "commentsEnabled": "pt:commentsEnabled",
      "sensitive": "as:sensitive",
      "matrixUserId": "lemmy:matrixUserId",
      "postingRestrictedToMods": "lemmy:postingRestrictedToMods",
      "removeData": "lemmy:removeData",
      "stickied": "lemmy:stickied",
      "moderators": {
        "@type": "@id",
        "@id": "lemmy:moderators"
      "expires": "as:endTime",
      "distinguished": "lemmy:distinguished",
      "language": "sc:inLanguage",
      "identifier": "sc:identifier"
  "actor": "",
  "to": [
  "object": {
    "id": "",
    "actor": "",
    "object": "",
    "type": "Like",
    "audience": ""
  "cc": [
  "type": "Announce",
  "id": ""

The information contained is that ‘RageAgainstTheRich’ upvoted the comment identified by “”. Using JSON-LD, we need 1,400 bytes to encode that information. Most of it is the LD part – once that is removed it drops down to 580 bytes. 580 is still a lot, considering English needs only ~100.

Kbin only has two lines in their @context and it federates fine.

PieFed adds the same @context that Lemmy does, for now. As far as I can tell it really doesn’t matter whether it is there or not or how complete it is and I might make a configuration setting that can turn it on or off.

One comment

Leave a Reply

Your email address will not be published. Required fields are marked *