Nostr-Core, Your New Favorite Libary
We built nostr-core so developers can focus on what they’re building instead of constantly wrestling with the details of the Nostr protocol.
If you’ve ever tried building something on Nostr, you probably know the feeling.
You start with a simple idea. Maybe it’s a social client, a marketplace, a tipping page, or something completely new. You open your editor, sketch out the feature you want to build, and then reality kicks in.
Within an hour you’re buried in protocol details. Event signing. Bech32 encoding. Shared secret derivation. Relay message parsing. Wallet Connect encryption.
And you still haven’t written a single line of the actual application you wanted to build.
At some point you realize you’re not building your product anymore. You’re implementing the protocol.
We’ve been there more times than we can count. Every new project started the same way: copy-pasting cryptographic helpers from old codebases, re-implementing the same NIPs, rediscovering the same edge cases, and debugging the same subtle issues again and again.
Eventually it became obvious that the ecosystem needed something simpler.
So we built nostr-core.
A Small Library That Handles the Hard Parts
nostr-core is an open-source JavaScript and TypeScript library that focuses purely on the protocol layer.
The goal isn’t to provide a full framework or dictate how applications should be built. Instead, it provides a clean and minimal interface to the core pieces every Nostr application needs: working with events, handling keys and signing, performing encryption, and interacting with Lightning through Wallet Connect.
Under the hood it relies on audited noble cryptography libraries and avoids pulling in unnecessary dependencies. There are no opinions about frameworks, state management, UI layers, or architecture.
It simply gives you the primitives required to speak the Nostr protocol safely and correctly.
Everything else is up to you.
Why We Took a Different Approach
A lot of existing Nostr libraries try to do everything.
They bundle relay pools, caching layers, subscription managers, event stores, UI bindings, and sometimes half a framework’s worth of abstractions. That can be convenient if you want exactly that stack, but it becomes painful when you only need a small piece of functionality.
If all you want to do is sign an event or decode an npub, you shouldn’t need to pull in a dependency tree large enough to inflate your bundle size or complicate audits.
nostr-core was intentionally designed in the opposite direction.
The library is small. The codebase is compact enough that you can realistically read through it in an afternoon and understand how everything works. There are only a handful of modules, and the dependency list is intentionally minimal.
In practice that means no unexpected runtime surprises, no deep chains of transitive dependencies, and no moments where you wonder why a tiny feature suddenly added megabytes to your build.
You import what you need, and the rest stays out of your application.
What nostr-core Handles Today
At its core, the library implements the fundamental mechanics of Nostr.
It can create, hash, sign, and verify events according to NIP-01, which forms the basis of everything else in the protocol. Signing is handled through a flexible abstraction that works with raw secret keys, browser extensions that implement NIP-07, and remote signing systems like nsecBunker via NIP-46. Switching between these approaches doesn’t require changing the rest of your application logic.
Encryption support covers both generations of Nostr messaging: the legacy NIP-04 AES scheme as well as the newer NIP-44 ChaCha20 construction with padding. Both operate through the same signer interface so developers don’t need to worry about the details of key agreement or cipher selection.
Private messaging is implemented using the modern NIP-17 model along with NIP-59 gift wrapping, which adds sender anonymity and better metadata protection.
The library also handles all NIP-19 bech32 encoding and decoding, making it straightforward to work with npubs, nsecs, notes, nprofiles, events, and addressable identifiers without constantly reimplementing encoding logic.
On the Lightning side, nostr-core includes a full client implementation for Nostr Wallet Connect (NIP-47). It can send payment requests, create invoices, check balances, perform keysend payments, retrieve transaction histories, and subscribe to payment notifications. It automatically detects whether the connected wallet uses NIP-04 or NIP-44 encryption.
For convenience, it also supports Lightning Address resolution, allowing applications to turn a simple name@domain identifier into a payable BOLT-11 invoice with a single call.
And since many payment interfaces need it, the library includes utilities for converting between satoshis and fiat currencies such as USD or EUR.
All of this ships as modern ESM modules and is fully tree-shakeable, meaning only the code you actually import ends up in your bundle.
Who This Is For
nostr-core is meant for developers working in JavaScript or TypeScript who want to integrate Nostr or Lightning without rebuilding the protocol stack from scratch.
That includes people building web clients, backend services, bots, payment widgets, or experimental tools. It works just as well in browsers, Node environments, Deno scripts, and mobile frameworks like React Native.
The guiding idea is simple: someone building a tipping widget shouldn’t need to understand the intricacies of elliptic-curve Diffie–Hellman key derivation. A team building a messaging client shouldn’t spend their first development sprint implementing gift-wrap cryptography.
Those problems are already solved.
nostr-core just makes the solutions easy to use. Browse our documentation to get started.
What Comes Next
The current version focuses on the core infrastructure needed for building Nostr applications, but there is plenty more on the roadmap.
Future additions include support for threading and replies, reactions, long-form content events, relay management, follow lists, zaps, badges, and broader LNURL functionality.
The project is developed completely in the open, and contributions are welcome.
You can follow development, browse issues, or jump in and contribute here:
https://github.com/nostr-core-org/nostr-core
Or you can simply install the library and start building something new. https://www.npmjs.com/package/nostr-core
That was the whole point from the beginning.