<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Jurjen de Vries</title>
    <description>The latest articles on Forem by Jurjen de Vries (@jurjendevries).</description>
    <link>https://forem.com/jurjendevries</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2453920%2F4daca9cf-8399-43ec-9feb-8317a36d2922.jpg</url>
      <title>Forem: Jurjen de Vries</title>
      <link>https://forem.com/jurjendevries</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/jurjendevries"/>
    <language>en</language>
    <item>
      <title>2025: The Year of Decentralization – How Nostr Will Make You a Standout Developer</title>
      <dc:creator>Jurjen de Vries</dc:creator>
      <pubDate>Wed, 15 Jan 2025 15:08:12 +0000</pubDate>
      <link>https://forem.com/jurjendevries/2025-the-year-of-decentralization-how-nostr-will-make-you-a-standout-developer-5f5l</link>
      <guid>https://forem.com/jurjendevries/2025-the-year-of-decentralization-how-nostr-will-make-you-a-standout-developer-5f5l</guid>
      <description>&lt;p&gt;Imagine this: It’s the beginning of 2025, and you’re scrolling through yet another article claiming the "next big thing" in tech. You’ve heard all the promises—decentralization, privacy, freedom—but in practice, most of these projects end up as just another centralized service in disguise. It feels like everything you touch still has gatekeepers, rent-seeking intermediaries, and barriers that prevent real, open innovation. Take Bluesky for example, which is a hot next big thing topic. While the protocol is decentralized, initially Bluesky Social (bsky.app) operated as the main centralized service. &lt;/p&gt;

&lt;p&gt;But what if, in this new year, this changes? What if you could be part of the movement that actually delivers on the dream of true decentralization? Nostr is here, and it’s unlike anything you’ve seen before.&lt;/p&gt;

&lt;p&gt;In the next few minutes, I’m going to show you why decentralization has struggled to live up to its potential, and how you, by diving into Nostr, can be at the forefront of the technology that finally gets it right. Spoiler: It’s not just about building cool apps—it’s about shaping the future and standing out in a crowded field of developers who are still following the old rules.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The Journey from Bulletin Boards to True Decentralization&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;I grew up at the end of the 80s, just a kid of 10 years old, fascinated by how we could exchange data even back then. Bulletin Boards were my gateway into a new world—a decentralized way to share knowledge, files, and ideas. There was no one stopping us, no one to say, “You can’t connect.” It felt free, and in many ways, it truly was. It was messy, sure, but it was ours.&lt;/p&gt;

&lt;p&gt;Then came the World Wide Web, and everything changed. Tim Berners-Lee’s vision was a web for everyone—open, accessible, a place where information was just a few clicks away. For a while, it really seemed like the world was opening up. I remember the excitement of those early years: building pages, following hyperlinks, feeling like the possibilities were endless.&lt;/p&gt;

&lt;p&gt;But slowly, those possibilities began to close up. Bit by bit, the open landscape of the web became a walled garden dominated by big tech giants. Platforms emerged, and with them, new gatekeepers. Where we once had the chaos of independence, we suddenly had convenience. Convenience offered by a handful of corporations who asked for our data in exchange for services.&lt;/p&gt;

&lt;p&gt;I’ve seen dozens of initiatives try to break free from that grip. Solid by Tim Berners-Lee himself, promising to give us back control of our data. Various Web 3 blockchains with grand visions of decentralization, but bogged down by tokenomics and complexity that alienated developers and users alike. I’ve even seen grassroots tools like Popcorn Time, which tried to distribute entertainment peer-to-peer and reclaim some of the internet’s original spirit of freedom.&lt;/p&gt;

&lt;p&gt;And yet, here we are, the beginning of 2025, still grappling with many of the same issues. Every time a new “decentralized” platform gains traction, it seems like we end up right back where we started—walled gardens, just with new labels.&lt;/p&gt;

&lt;p&gt;But then there’s Nostr. And for the first time in a long time, I’m seeing something different. Something that actually holds true to the spirit of openness I remember from the Bulletin Board days. Nostr isn’t trying to sell me a token, and it’s not hiding behind the convenience of centralized infrastructure. It’s an open protocol that anyone can use, contribute to, and build upon, without a gatekeeper standing at the door.&lt;/p&gt;

&lt;p&gt;Nostr is about shaping the future and standing out in a crowded field of developers who are still following the old rules. Where Popcorn Time got blocked by centralized app stores, Nostr clients connect to relays that can't be shut down in the same way. Thanks to clients like &lt;a href="https://github.com/zapstore" rel="noopener noreferrer"&gt;zap.store&lt;/a&gt;, Nostr offers decentralized app distribution that works—giving developers the freedom to innovate without arbitrary restrictions.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The Problems with Current Decentralization Efforts&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Platform Failures: The Illusion of Decentralization&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;For years, we’ve seen countless projects enter the spotlight claiming to be the next big decentralized solution—only for them to fall into the same traps that have always plagued centralized platforms. The problem often lies in the architecture; even though these projects advertise themselves as decentralized, they still rely on a backbone of central servers or infrastructure that ends up reintroducing the very intermediaries they were meant to replace.&lt;/p&gt;

&lt;p&gt;Take, for example, &lt;a href="https://solidproject.org/" rel="noopener noreferrer"&gt;Solid&lt;/a&gt;, Tim Berners-Lee’s personal data storage initiative. Solid had, and still has, a powerful vision: allowing users to regain control over their personal data by storing it in individual pods. However, the complexity of implementing and maintaining this system means that, in practice, many of these “pods” end up hosted on centralized services. It’s technically challenging for the average user to truly self-host, which means that, ultimately, the power shifts back into the hands of a few entities providing the hosting. The original promise of openness and freedom becomes diluted under the weight of technical barriers and centralized dependencies.&lt;/p&gt;

&lt;p&gt;The same fate has met several other Web3 platforms. They may start with decentralized intentions, but the compromises for scalability, usability, or monetization often bring back centralized intermediaries—whether it's trusted validators, foundation-controlled infrastructure, or third-party APIs that are difficult to replace.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Tokenomics and Complexity: The Barrier to Entry&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Then there’s the issue of blockchain-based decentralization, where tokenomics play a central role. On paper, blockchain technologies promised a fully decentralized world—one that’s not owned or controlled by anyone. However, reality is often much more convoluted. Blockchain projects almost always require some form of token or cryptocurrency to participate, making their ecosystems inherently exclusive and difficult for the average developer or user to access.&lt;/p&gt;

&lt;p&gt;The dependency on tokens as a fundamental part of the ecosystem creates a barrier. Instead of empowering everyone, it ends up creating a system where only those with enough of a certain token can participate freely. For someone just looking to build or use a decentralized application, the need to acquire, trade, and manage tokens becomes an obstacle. It’s a pay-to-play model that feels counterintuitive to the ethos of free and open participation that true decentralization should represent.&lt;/p&gt;

&lt;p&gt;Additionally, the tokenomics structure often adds layers of &lt;strong&gt;complexity&lt;/strong&gt; that make the system less approachable. Concepts like staking, liquidity pools, and governance tokens may make sense to crypto enthusiasts, but they are alienating for developers who simply want to build useful, impactful technology without needing to understand complex economic models.&lt;/p&gt;

&lt;p&gt;These token-based projects tend to attract speculation rather than actual utility-focused development. Instead of focusing on building resilient, open applications, the attention gets diverted to managing value, price fluctuations, and token distribution. a far cry from the original promise of freedom and innovation.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The Nostr Difference: A Truly Open Solution&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;This is where Nostr comes in, and why it feels like such a breath of fresh air. Nostr isn't about tokens, ICOs, or complex governance models. It's about simplicity. An open protocol that is easy for anyone to understand, implement, and build upon. Nostr doesn't ask for your money or require you to buy into a coin. Instead, it offers tools that you can use to create whatever you imagine, without any strings attached. Nostr stands for Notes and Other Stuff Transmitted by Relays.&lt;/p&gt;

&lt;p&gt;One of Nostr's most powerful features is its user identity system based on public key cryptography. Users are identified by their public keys across all Nostr applications, meaning your identity seamlessly works everywhere in the Nostr ecosystem - from social media to payment apps to game platforms. Unlike traditional platforms where you need separate accounts for each service, your Nostr identity is truly portable and under your control.&lt;/p&gt;

&lt;p&gt;The protocol is extended through NIPs (Nostr Implementation Possibilities) - standardized specifications that ensure consistent implementation across the ecosystem. These NIPs define different 'Kinds' of events. So besides Notes there are plenty of possibilities for Other Stuff such as an app store, reviews, payments and so on, allowing developers to build interoperable applications while maintaining the protocol's simplicity. This standardization means that innovations by one developer can be easily adopted by others, fostering a vibrant ecosystem of compatible apps and services.&lt;/p&gt;

&lt;p&gt;And Nostr's reliance on a network of relays, rather than a centrally controlled server, means that the power is distributed. You can host your own relay if you want to, or join one that aligns with your interests and values. There are no gatekeepers—no app stores that can block your software, as was the fate of Popcorn Time, which was continuously shut down by centralized app stores and blocked by ISPs.&lt;/p&gt;

&lt;p&gt;With projects like zap.store, Nostr is showing that decentralized app distribution can work in a more open, resilient manner. Apps on zap.store are tied to social profiles validated by trust networks, not centralized app store approvals. This ensures that developers can reach users without arbitrary gatekeeping. A significant step towards realizing the promise of a truly open internet.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;How to Get Started with Nostr&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;In a tech landscape where many developers adhere to traditional, centralized paradigms, embracing Nostr offers a unique opportunity to distinguish yourself. By diving into this open protocol, you can contribute to a truly decentralized ecosystem and set yourself apart in a field crowded with conventional approaches. Here's how you can get started:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Understanding Nostr: The Basics&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Nostr is a simple, open protocol that enables decentralized communication. Unlike traditional platforms, Nostr doesn't rely on central servers. Instead, it uses a network of relays to transmit messages, ensuring that no single entity has control over the flow of information.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Getting Started with Nostr: A Step-by-Step Guide&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;For beginners eager to explore Nostr, the &lt;a href="https://hellonostr.dev/" rel="noopener noreferrer"&gt;Hello Nostr Docs&lt;/a&gt; provide a comprehensive introduction. Here's a simplified walkthrough to send your first Nostr message:&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;1. Create HTML &amp;amp; Import the Nostr Tools Library&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;This tutorial requires the nostr-tools library to generate keys, create events, and interact with the Nostr network. We will use version 2.10.4 of the library. To import the Nostr Tools library in a browser environment, we need to first create an HTML file. Below is an HTML layout with a form to send a Nostr message with some basic styling.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
      &lt;span class="nf"&gt;#relays&lt;/span&gt;&lt;span class="nd"&gt;:not&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;:empty&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="nd"&gt;::before&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;"Published on:"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bold&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"nostr"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt;
        &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"note"&lt;/span&gt;
        &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"#hellonostr"&lt;/span&gt;
        &lt;span class="na"&gt;placeholder=&lt;/span&gt;&lt;span class="s"&gt;"Enter your message"&lt;/span&gt;
        &lt;span class="na"&gt;required&lt;/span&gt;
      &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Send&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"keys"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"relays"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"module"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;NostrTools&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://esm.sh/nostr-tools@2.10.4&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;type="module"&lt;/code&gt; attribute is necessary to use ES modules in the browser. And, it allows us to use &lt;code&gt;async/await&lt;/code&gt; which we are going to use below.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: The code snippets below should be placed inside the above &lt;code&gt;&amp;lt;script type="module"&amp;gt;&lt;/code&gt; tag.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;2. Define the Required Variables&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Let’s define the required variables that we will use in the following steps.&lt;/p&gt;

&lt;p&gt;In the web, we need to get the required elements and listen to the form submission event. We’ll also define the message content &amp;amp; list of relays where we want to publish the message.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;nostr&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="nx"&gt;keys&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;keys&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="nx"&gt;relays&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;relays&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;relayUrls&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;wss://relay.damus.io&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;wss://nostr.gleeze.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;wss://frysian.nostrich.casa&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;wss://nostr-01.yakihonne.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;submit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FormData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;note&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Get the message content&lt;/span&gt;

  &lt;span class="c1"&gt;// Snippets below will go here&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;strong&gt;3. Key Generation&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;First, we generate a new private key, which can be in different formats: Uint8Array (byte array for raw data processing), hex (human-readable), or Bech32 (error-resistant, human-readable format). Here is the key generation process:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Generate a new private key in Uint8Array format&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;privKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;NostrTools&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generateSecretKey&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Get the public key in hex format from the private key&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pubKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;NostrTools&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getPublicKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;privKey&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Display private and public keys in Bech32 (nsec/npub) format&lt;/span&gt;
&lt;span class="nx"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Private Key&amp;lt;/b&amp;gt;: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;NostrTools&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nip19&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;nsecEncode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;privKey&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;Public Key: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;NostrTools&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nip19&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;npubEncode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pubKey&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/li&amp;gt;
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;strong&gt;4. Create and Sign an Event&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Next, we create a Kind 1 event (a note) and sign it with the private key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Create a new Nostr event&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;NostrEvent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Kind 1 is a text note&lt;/span&gt;
  &lt;span class="na"&gt;pubkey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;pubKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;created_at&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="c1"&gt;// Unix timestamp in seconds&lt;/span&gt;
  &lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="c1"&gt;// Array of references to other events ('e'), pubkeys ('p') or addressable content ('a')&lt;/span&gt;
  &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Your message content, defined in Step 2&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// Sign the event with the private key&lt;/span&gt;
&lt;span class="nx"&gt;NostrEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;NostrTools&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getEventHash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;NostrEvent&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;NostrEvent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;NostrTools&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;finalizeEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;NostrEvent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;privKey&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Log the signed event&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Signed event:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;NostrEvent&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;strong&gt;5. Connect to Relays and Send the Event&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;To broadcast the event to the Nostr network, we connect to relay servers via WebSockets. You can find a list of known relays at &lt;a href="https://nostr.watch/" rel="noopener noreferrer"&gt;https://nostr.watch/&lt;/a&gt;. The relays handle the event in JSON format. Here’s how we send the event:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Clear previous relay list&lt;/span&gt;
&lt;span class="nx"&gt;relays&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Display the relays where the message was published&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;displayRelays&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contentHTML&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;relays&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;insertAdjacentHTML&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;beforeend&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;contentHTML&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;relayUrls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;socket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;WebSocket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onopen&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Connected to &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Send the signed event to the relay in JSON format&lt;/span&gt;
    &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;EVENT&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;NostrEvent&lt;/span&gt;&lt;span class="p"&gt;]));&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onmessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Message from &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nf"&gt;displayRelays&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&amp;lt;li&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/li&amp;gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Display relay URL&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onclose&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Disconnected from &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Clear the form&lt;/span&gt;
&lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reset&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code connects to the relays and publishes your signed event. For more detailed guidance, refer to the &lt;a href="https://hellonostr.dev/en/step-by-step-guide/" rel="noopener noreferrer"&gt;Hello Nostr Step-by-Step Guide&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Summary of the Process
&lt;/h3&gt;

&lt;p&gt;To recap, here’s the process for sending a Nostr message:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Key Generation: We generated a private/public key pair using Nostr tools.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Creating and Signing an Event: We created a Kind 1 event (a note) and signed it with the private key.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Connecting to Relays: We connected to multiple relay servers using WebSockets to ensure the message was distributed across the Nostr network.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Displaying Published Relays: We displayed the relays where the message was successfully published.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Advanced Development with Nostr&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;For developers looking to integrate Nostr into their applications using popular programming languages, several libraries are available:&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;JavaScript: nostr-tools&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;The &lt;a href="https://github.com/nbd-wtf/nostr-tools/" rel="noopener noreferrer"&gt;nostr-tools&lt;/a&gt; library offers a suite of utilities for building Nostr clients in JavaScript. It provides functions for key generation, event creation, signing, and relay management.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;PHP: nostr-php&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;The &lt;a href="https://github.com/nostrver-se/nostr-php" rel="noopener noreferrer"&gt;nostr-php&lt;/a&gt; library is a PHP helper for Nostr. It allows developers to create and sign events, manage keys, and interact with relays.&lt;/p&gt;

&lt;p&gt;For examples and detailed usage, consult the &lt;a href="https://github.com/nostrver-se/nostr-php" rel="noopener noreferrer"&gt;nostr-php GitHub repository&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Other languages&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Looking for your favorite language such as &lt;a href="https://github.com/nbd-wtf/go-nostr" rel="noopener noreferrer"&gt;Go&lt;/a&gt;, &lt;a href="https://github.com/Kukks/NNostr" rel="noopener noreferrer"&gt;C#&lt;/a&gt;, &lt;a href="https://github.com/tcheeric/nostr-java" rel="noopener noreferrer"&gt;Java&lt;/a&gt;, &lt;a href="https://github.com/Giszmo/NostrPostr" rel="noopener noreferrer"&gt;Kotlin&lt;/a&gt; or &lt;a href="https://github.com/jeffthibault/python-nostr" rel="noopener noreferrer"&gt;Python&lt;/a&gt;? Many more are available by &lt;a href="https://github.com/aljazceru/awesome-nostr?tab=readme-ov-file#libraries" rel="noopener noreferrer"&gt;https://github.com/aljazceru/awesome-nostr?tab=readme-ov-file#libraries&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Wrapping Up: Be a Part of the Movement&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;As we stand in the beginning of 2025, the landscape of decentralization is evolving, and Nostr is at the forefront of this transformation. By embracing Nostr, you're not just adopting a new protocol; you're positioning yourself as a pioneer in a movement that champions true openness and user empowerment. Many Twitter/X Clones are already been developed and some 'Other Stuff' such as the Zap.Store too. What would you like to build or convert? Let me know in the comments.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Why Nostr Matters&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Nostr's simplicity and commitment to decentralization address the shortcomings of previous attempts that often fell into centralization traps or were bogged down by complex tokenomics. Its open protocol allows developers to build without the constraints of centralized platforms, fostering innovation and creativity.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Getting Involved&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Whether you're a seasoned developer or just starting, Nostr offers a welcoming community and a wealth of resources to help you get started. From building your first client to contributing to existing projects, the opportunities are vast.&lt;/p&gt;

&lt;p&gt;If you plan to visit &lt;a href="https://fosdem.org/2025/" rel="noopener noreferrer"&gt;FOSDEM February 2025&lt;/a&gt; in Bruxelles, Belgium feel free to visit the Nostr stand and the Nostr talk by Constant at the mainstage.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Join the Conversation&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;We'd love to hear your thoughts and experiences with decentralization and Nostr. Have you experimented with Nostr clients like &lt;a href="https://primal.net/" rel="noopener noreferrer"&gt;Primal&lt;/a&gt; (all), &lt;a href="https://damus.io/" rel="noopener noreferrer"&gt;Damus&lt;/a&gt; (iOS) or &lt;a href="https://github.com/vishalxl/Nostr-Clients-Features-List" rel="noopener noreferrer"&gt;Amethyst&lt;/a&gt; (Android)? What challenges or successes have you encountered? Share your insights in the comments below, post your Hello World on Nostr by #hellonostr with your own code, or get in touch by &lt;a href="https://njump.me/npub1l77twp5l02jadkcjn6eeulv2j7y5vmf9tf3hhtq7h7rp0vzhgpzqz0swft" rel="noopener noreferrer"&gt;Nostr&lt;/a&gt; or &lt;a href="https://discord.com/invite/nGnEkDzQ6S" rel="noopener noreferrer"&gt;Discord&lt;/a&gt; and let's build a community of developers dedicated to shaping the future of a truly decentralized internet.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>opensource</category>
      <category>web3</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
