Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add NIP-74: Nostr Link Lists #1753

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

vveerrgg
Copy link

@vveerrgg vveerrgg commented Feb 6, 2025

NIP-74: Nostr Link Lists

This NIP defines a standardized format for sharing curated collections of links on Nostr. It formalizes and extends the format originally developed by nostree.me, which has been successfully serving the Nostr community as a "link-in-bio" solution.

Key Features

  • Public link list events (kind:30011 - where "11" visually resembles "ll" for "link list")
  • Rich metadata and internationalization support
  • Protocol-specific link handling (http, magnet, ipfs, etc.)
  • Complements NIP-51 bookmarks by focusing on public sharing

Distinction from NIP-51 Bookmarks

While NIP-51 bookmarks serve as private reading lists, NIP-74 link lists are designed for public sharing and discovery, enabling users to curate and share collections of resources with their community.

Implementation Status

This format evolved from the proven implementation at nostree.me, which has been serving the Nostr community as a reliable link-sharing platform. The specification has been refined based on real-world usage and community feedback, and is also being implemented by other projects like linktr-nostr, demonstrating its practical utility and growing adoption.

References

This NIP defines a standardized format for sharing curated collections of links on Nostr. Key features:
- Public link list events (kind:30001)
- Rich metadata and internationalization support
- Protocol-specific link handling
- Complements NIP-51 bookmarks by focusing on public sharing

The NIP number 74 was chosen as it represents ASCII 'L' for Links.
@AsaiToshiya
Copy link
Collaborator

Why is there no d tag even enough it is an addressable event?

- Replace title tag with 'd' tag to follow NIP-51 convention
- Update tag description to clarify its purpose
- Keep consistent with other list-type NIPs
@vveerrgg
Copy link
Author

vveerrgg commented Feb 6, 2025

good catch ... I changed the title field to a d field.

- Update from 30001 (which was previously deprecated) to 30011
- Update all examples and documentation to use new kind number
The '11' in 30011 visually resembles 'll' for 'link list', adding a mnemonic element to the kind number choice.
### Tags

Required tags:
- `ll` ["list"] - Identifies this as a link list event
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is the ll tag needed? I think event kind is enough.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the feedback! The suggestion to use kind:30001 with a "d" tag is thoughtful, but I believe link lists warrant their own kind number for several important reasons:

  1. Distinct Purpose & Evolution: While NIP-51 lists are primarily for personal organization (bookmarks, pins, etc.), link lists serve a fundamentally different purpose. They're designed for public sharing and can evolve into:

    • Site navigation systems
    • Resource directories
    • Content curation tools
    • Public profile components
    • Community knowledge bases
  2. Rich Metadata & Protocol Support: Link lists need specialized handling for:

    • Multiple protocol types (http, magnet, ipfs, nostr, etc.)
    • Protocol-specific metadata and validation
    • Language/internationalization per link
    • Direction handling for RTL languages
  3. Implementation Clarity: A distinct kind number makes it clear to implementers that:

    • This is a public-facing feature (vs. personal lists)
    • It requires specific UI/UX considerations
    • It needs protocol-aware handling
    • It may evolve independently of personal lists

Regarding the ll tag: While the kind does indicate "this is a link list", the tag serves additional purposes:

  1. Makes it easier to filter/query specifically for link lists
  2. Allows for future extensions without kind number changes
  3. Maintains consistency with other NIPs that use identifying tags

The goal is to create a foundation for rich, public link-sharing features that can grow beyond simple lists while maintaining clear separation from personal bookmarking tools.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And to add a concrete example: One of the implementation I had envisioned is a "Top 8 Nostr Friends" feature (similar to MySpace) where users can showcase their closest connections or most meaningful interactions. This would use the same link list structure but with:

  • npub-specific metadata
  • Optional interaction-based auto-generation
  • Custom display ordering
  • Profile-specific metadata (last interaction, relationship, etc.)

This kind of extension demonstrates why having a dedicated kind with additional metadata support is valuable - it allows link lists to evolve from simple URL collections into richer social features while maintaining backward compatibility.

@staab
Copy link
Member

staab commented Feb 6, 2025

I think this is pretty much covered by NIP 51 bookmarks. Given that events are public, they can't not be for public consumption. If someone wants private bookmarks, they should encrypt them into their 10003 event's content. We also have a standard for external content ids which can already be added to any kind of list.

@fiatjaf
Copy link
Member

fiatjaf commented Feb 6, 2025

At best this should be just one extra row added to the NIP-51 table.

@vveerrgg
Copy link
Author

vveerrgg commented Feb 6, 2025

Thank you for taking the time to review and feedback. It's definitely giving me pause in thinking about the relationship between bookmarks and link lists. The project I've been quietly working on is a link-in-bio" type page. So I might be overly focused on lists of a specific type. That may still be an edge case to most other users of the Nostr protocol.

And while there's definitely overlap, I'm seeing some distinct patterns emerge from real-world usage (in nostree.me) and wanted to open the idea up from an edge case to its own NIP:

  1. Intent & Discovery

    • Bookmarks (even public ones) are primarily personal (public) collections for future reference, and not considered living artifacts that are referenced / evolved over time
    • Link lists are specifically curated for sharing/discovery (like "check out these resources" or "my favorite nostr clients") with the intent of being a living artifact that has renditions that evolve over time
    • The distinction is similar to "saving an article (to a list) to read later" vs "publishing a curated reading list for reference / presentation as an artifact"
  2. Structured Metadata

    • Link lists often need richer metadata for display and organization
    • Protocol-specific handling (nostr:, ipfs:, magnet:)
    • Language/direction per link for international communities
    • Link categories and types
  3. UI/UX Considerations

    • Different presentation needs (e.g., "link in bio" style pages)
    • Discovery-focused features
    • Protocol-aware rendering

That said, I completely understand the desire to avoid unnecessary complexity in the protocol. Would it make sense to:

  1. Extend NIP-51 bookmarks with optional metadata tags for these cases?
  2. Add guidelines for clients about different presentation modes?
  3. Document these patterns in the NIP-51 implementation notes?

As a "new to Nostr" UX/UI developer, I'm happy to help draft these additions to NIP-51 if that's the preferred approach. My intentions / goal is to support these emerging use cases while maintaining protocol simplicity.

@staab
Copy link
Member

staab commented Feb 6, 2025

The project I've been quietly working on is a link-in-bio" type page.

Consider https://github.com/nostr-protocol/nips/blob/master/39.md

Bookmarks (even public ones) are primarily personal (public) collections for future reference, and not considered living artifacts that are referenced / evolved over time

I think this is fair. A new NIP 51 kind could probably be justified. Or, you could imitate coracle's "collections", which use NIP 32 (probably not the best idea though).

Protocol-specific handling (nostr:, ipfs:, magnet:)

Consider https://github.com/nostr-protocol/nips/blob/master/92.md

That said, I completely understand the desire to avoid unnecessary complexity in the protocol.

I do think that's what this spec is mostly in danger of right now. There is a balance between complexity and interoperability. If a spec is too simple, it won't support rich interactions. If a spec is too complex, it won't be interoperable. This is the reason nostr specs are so barebones; you can add whatever fancy meta tags you want, but if no one bothers to implement them because their utility doesn't meet the threshold of development expense or usefulness to interop, then they fail to be any kind of protocol at all.

@Semisol
Copy link
Collaborator

Semisol commented Feb 6, 2025

good catch ... I changed the title field to a d field.

what if you want to change the title?

@staab
Copy link
Member

staab commented Feb 6, 2025

what if you want to change the title?

Best practice is to use a random id for the d tag for this reason

@vveerrgg
Copy link
Author

vveerrgg commented Feb 6, 2025

Wow these are great insights... Thank you!!! I'm still learning the landscape of the protocol, and the feedback here definitely makes sense. Reading into the suggested NIPs, and also trying to bring value without complexity, I think the best way forward might be:

  • Pull back NIP-74 as it's not unique enough to warrant a differentiator to NIP-51
  • Focus on adding a minimal, focused kind to NIP-51 to help account for language, LtR/RtL
  • Leverage (and learn more about) existing NIPs (39, 92) for advanced features for Link-In-Bio type projects
  • Stay true to the core simple but extensible ethos of the protocol

As a next step, I can draft a simple addition to NIP-51's table for a "curated links" kind that focuses just on the essential metadata (language, direction) while leveraging existing NIPs for the rest. Would that be a helpful contribution?

I'm grateful for all the feedback here, and the constructive conversation. As a new to Open Source contributor, I'm excited to be part of the Nostr community, and learning how to participate in a "yes and" way without creating chaos.

@fiatjaf
Copy link
Member

fiatjaf commented Feb 6, 2025

In this case wouldn't it be better to make it a normal replaceable event?

@vveerrgg
Copy link
Author

vveerrgg commented Feb 6, 2025

Yes, that what I was thinking. That each update would replace the rendition shown, on the users bio. As a regular replaceable event, it would be simpler / fits the use case better - with the idea that users typically want one main link list that they update over time.

Would something like this work as an addition to NIP-51?
| Curated Links | 10005 | Public list of links with display metadata | "nl" [url, description, language?, direction?], "t" (topics) |

This would give users one update-able link list while still supporting the metadata we need for good i18n support, and follows the sequence of existing list kinds (10000-10004).

@staab
Copy link
Member

staab commented Feb 6, 2025

The 10005 kind looks good to me.

"nl" [url, description, language?, direction?]

Why language and direction? Shouldn't that be handled by the website serving the url? It seems like odd metadata to include.

@vveerrgg
Copy link
Author

vveerrgg commented Feb 6, 2025

Good question and thank you for asking.

My thoughts have been that language/direction metadata might seem redundant at first, but ... I wanted to reflective to real-world experiences with multilingual applications.

One of the UX considerations I'm hoping we would cover is the nuance of a global audience mixing their link sources in a single list. And you're right. Websites / browsers handle their own language/direction. By having this metadata at the link level serves a few practical purposes:

  1. User Experience: It lets clients pre-inform users about the language they're about to encounter, rather than having them click through to discover it
  2. Accessibility: Screen readers and assistive technologies can prepare for the correct language/pronunciation before navigating
  3. Mixed Language Lists: It enables curators to build truly global link collections where each link can be properly presented in its native language/direction
  4. Smart Filtering: Clients can filter/group links by language preference without having to fetch each URL

I learned this pattern working on a handful of corporate applications - it's particularly helpful when building interfaces that seamlessly mix content in languages like English (LTR) with Arabic (RTL) or if there are links that are English, and Chinese (simplified/traditional), or Japanese.

That said, these are optional fields (hence the ? in the spec). Clients can ignore them if they don't need this functionality, but having them available opens up some nice possibilities for more inclusive, global-first applications.

@staab
Copy link
Member

staab commented Feb 7, 2025

This seems like over-engineering to me. You could make just as strong a case for 1000 other dimensions of what might be behind a link, which gets up back into scope-creep territory again. Maybe these particular pieces of metadata are more important than I think, or maybe they're crucial to your use case. But I would be surprised if the average client adapted its UI to that extra metadata (meaning in practice interoperability wouldn't happen).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants