Stop Over-Engineering Your Lightning Wallet Integration

Meet nostr-core: a dead-simple NWC client that does exactly what you need - and nothing more.
If you've ever tried to add Lightning payments to a JavaScript app, you've probably hit a familiar wall: bloated SDKs, vendor lock-in, and dependency trees that could fill a phone book.
I want to introduce you to nostr-core - a minimal, vendor-neutral Nostr Wallet Connect (NWC) client that strips away the noise and lets you focus on building.
The Problem with Existing Solutions
Most Lightning wallet SDKs come with baggage. You want to pay an invoice - simple enough, right? But the SDK you install drags in 400+ packages, couples you to a specific provider's OAuth flow, and requires you to learn an API surface with five different classes before you can send a single satoshi.
There's a better way.
One Connection String. That's It.
Here's what it looks like to connect to a wallet and check your balance with nostr-core:
import { NWC } from 'nostr-core'
const nwc = new NWC('nostr+walletconnect://...')
await nwc.connect()
const { balance } = await nwc.getBalance()
console.log(`Balance: ${balance} msats`)
No OAuth. No configuration objects. No provider-specific setup. You pass in a standard NWC connection URI, and you're ready to go.
Pay an Invoice in Three Lines
const { preimage } = await nwc.payInvoice('lnbc...')
console.log('Paid! Preimage:', preimage)
nwc.close()
That's a complete payment flow. Connect, pay, done.
Lightning Address Payments - Built In
One of the standout features is native Lightning Address support. No extra dependencies, no separate libraries:
const { preimage } = await nwc.payLightningAddress('hello@getalby.com', 100)
console.log('Paid 100 sats!')
Need fiat conversion? Also built in:
const { preimage, sats, rate } = await nwc.payLightningAddressFiat(
'hello@getalby.com', 5, 'usd'
)
console.log(`Paid \({sats} sats (\)5 at $${rate}/BTC)`)
Error Handling That Actually Helps
Instead of catching generic errors and guessing what went wrong, nostr-core gives you a typed error hierarchy:
import { NWCWalletError, NWCTimeoutError, NWCConnectionError } from 'nostr-core'
try {
await nwc.payInvoice('lnbc...')
} catch (err) {
if (err instanceof NWCWalletError) {
// The wallet said no maybe insufficient balance
console.error(`Wallet rejected [\({err.code}]: \){err.message}`)
} else if (err instanceof NWCTimeoutError) {
// Relay or wallet didn't respond in time
console.error('Timed out:', err.code)
} else if (err instanceof NWCConnectionError) {
// WebSocket dropped
console.error('Connection lost')
}
}
Eight specific error classes cover every failure mode: wallet rejections, publish failures, relay timeouts, decryption issues, Lightning Address resolution errors, and fiat conversion problems. No more guesswork.
What's Under the Hood
nostr-core is built on top of the audited noble cryptography libraries - the same ones used across the broader Nostr ecosystem. It auto-detects whether your wallet supports NIP-04 or NIP-44 encryption and handles everything transparently.
The full NIP-47 spec is covered: pay_invoice, get_balance, make_invoice, list_transactions, pay_keysend, sign_message, and more.
And it runs everywhere -Node.js 18+, Deno, Bun, Cloudflare Workers. Anywhere with Web Crypto and WebSocket support.
The Numbers Don't Lie
Here's how nostr-core stacks up against the most common alternative:
Metric | nostr-core | Alternative |
|---|---|---|
Install size | 118 MB | 159 MB |
Packages installed | 79 | 436 |
Total dependency tree | 132 | 698 |
That's 26% smaller, with 82% fewer packages. Fewer dependencies means fewer supply chain risks, faster installs, and less surface area for things to break.
Who Should Use This?
If you're building anything that needs Lightning payments in JavaScript or TypeScript a web app, a bot, a CLI tool, a backend service and you don't need provider-specific features like OAuth flows, nostr-core is almost certainly the right choice.
It's ESM-only, tree-shakeable, and exposes a single NWC class. The learning curve is measured in minutes, not hours.
Get Started
npm install nostr-core
Check out the demo and the GitHub repository for full documentation.
nostr-core is MIT licensed and built on audited noble cryptography libraries. No vendor lock-in, no framework dependencies, no surprises.



