Educational Calendar Events — live demo

How to read educational calendar events (NIP-52) from relay.edufeed.org and render them in different designs. The write side — publishing events with educational metadata (registration, price, attendance mode, educational level) — is covered in the Educational Calendar Events integration guide (draft); both pages describe the same events. The educational extension attributes are a draft — this demo reads the plain NIP-52 events published today.

What you get NIP-52

The relay wss://relay.edufeed.org publishes educational calendar events as NIP-52 events on the Nostr protocol. There are four kinds:

kind 31922 — date-based

Full-day or multi-day events. start / end are YYYY-MM-DD strings.

kind 31923 — time-based

Events with a specific time. start / end are unix timestamps; optional start_tzid.

kind 31924 — calendar

A collection that references other events via a-tags. Used to group events into named calendars.

kind 31925 — RSVP

A reply to an event with a status tag of accepted, declined, or tentative.

Fetch via WebSocket (browser)

Nostr is a plain WebSocket protocol. Open a socket, send a REQ frame describing the kinds you want, then collect EVENT messages until you receive EOSE (end of stored events). This is exactly what the demo below does:

const ws = new WebSocket("wss://relay.edufeed.org");
ws.onopen = () => {
  ws.send(JSON.stringify([
    "REQ", "cal-sub",
    { kinds: [31922, 31923], limit: 500 }
  ]));
};
ws.onmessage = (msg) => {
  const [type, sub, payload] = JSON.parse(msg.data);
  if (type === "EVENT") render(payload);
  if (type === "EOSE")  ws.send(JSON.stringify(["CLOSE", sub]));
};

Fetch via CLI (nak)

For scripts and backups, the nak tool works well:

nak req --paginate --paginate-interval 1s \
  -k 31922 -k 31923 -k 31924 -k 31925 \
  relay.edufeed.org > calendar-events.jsonl

Live demo

idle
Loading events from the relay…

Standalone — no build step, no external scripts. Save this file and open it in a browser.