NOSTR_LOGIN_LITE
A minimal, dependency-light replacement for the current auth/UI stack that preserves all login methods and window.nostr surface.
Features
- ✅ Single file distributable (
nostr-login-lite.bundle.js) - ✅ All major login methods: Extension, Local key, Read-only
- ✅ Compatible window.nostr facade
- ✅ NIP-04 and NIP-44 encryption (local)
- ✅ Minimal vanilla JavaScript modal
- ✅ No bulky frameworks (no Stencil/Tailwind)
- ✅ Just ~50KB gzipped (minus nostr-tools)
Installation
<!-- 1. Load nostr-tools (local bundle) -->
<script src="./lite/nostr.bundle.js"></script>
<!-- 2. Load NOSTR_LOGIN_LITE -->
<script src="./lite/nostr-login-lite.bundle.js"></script>
Quick Start
// Initialize with default options
await window.NOSTR_LOGIN_LITE.init({
theme: 'light',
relays: ['wss://relay.damus.io'],
methods: {
extension: true,
local: true,
readonly: true
}
});
// Launch login modal
window.NOSTR_LOGIN_LITE.launch();
API Reference
Initialization
// Initialize the library
await window.NOSTR_LOGIN_LITE.init(options)
// Options
{
theme: 'light' | 'dark',
darkMode: boolean,
relays: string[], // Default relays for NIP-46
methods: {
connect: boolean, // NIP-46 providers (coming)
extension: boolean, // Browser extensions
local: boolean, // Local key generation
readonly: boolean, // Read-only mode
otp: boolean // OTP/DM (coming)
}
}
User Interface
// Launch authentication modal
window.NOSTR_LOGIN_LITE.launch(startScreen);
// Available screens
'login' // Auth selection
'signup' // Account creation
'switch' // Account switching
// Logout current user
window.NOSTR_LOGIN_LITE.logout();
// Set theme
window.NOSTR_LOGIN_LITE.setDarkMode(dark: boolean);
Programmatic Auth
// Set authentication manually
window.NOSTR_LOGIN_LITE.setAuth({
type: 'login' | 'signup' | 'logout',
method: 'extension' | 'local' | 'readonly' | 'connect' | 'otp',
pubkey: string, // Public key
secret: string // Private key (optional)
});
// Cancel ongoing auth flow
window.NOSTR_LOGIN_LITE.cancelNeedAuth();
window.nostr Compatibility
All standard window.nostr methods work transparently:
// Get current user's public key
const pubkey = await window.nostr.getPublicKey();
// Sign an event
const signed = await window.nostr.signEvent({
kind: 1,
content: 'Hello Nostr!',
tags: [],
created_at: Date.now()
});
// NIP-04 encrypt/decrypt
const encrypted = await window.nostr.nip04.encrypt(recipientPubkey, 'secret');
const decrypted = await window.nostr.nip04.decrypt(senderPubkey, encrypted);
// NIP-44 encrypt/decrypt (if available in nostr-tools)
const encrypted = await window.nostr.nip44.encrypt(recipientPubkey, 'secret');
const decrypted = await window.nostr.nip44.decrypt(senderPubkey, encrypted);
Events
Listen for authentication events:
// Auth state changes
window.addEventListener('nlAuth', (event) => {
console.log(event.detail);
// { type: 'login', pubkey: '...', method: 'local' }
});
// Dark mode changes
window.addEventListener('nlDarkMode', (event) => {
document.body.classList.toggle('dark', event.detail.dark);
});
// Auth URLs (for NIP-46)
window.addEventListener('nlAuthUrl', (event) => {
console.log('Auth URL:', event.detail.url);
});
// Logout events
window.addEventListener('nlLogout', () => {
console.log('User logged out');
});
Architecture
NOSTR_LOGIN_LITE/
├── nostr-login-lite.bundle.js # Single distributable
├── core/
│ ├── nip46-client.js # NIP-46 transport over websockets
│ └── {other components} # Future components
├── ui/
│ └── modal.js # Vanilla JS modal
└── README.md # This file
Key Components
- Modal: Lightweight modal using vanilla CSS
- Store: localStorage helpers for accounts/relays
- LocalSigner: Wraps nostr-tools for local signing
- ExtensionBridge: Detects and bridges browser extensions
- NIP46Client: Handles remote signing (NIP-46)
- Relays: Default relay management
Browser Support
- Modern browsers with ES2018+ support
- WebWorkers (for NIP-46)
- localStorage (for account storage)
Dependencies
This project uses a local copy of nostr-tools instead of loading from CDN:
- nostr.bundle.js: Local nostr-tools bundle (~200KB)
- nostr-login-lite.bundle.js: This library (~50KB gzipped)
Size Comparison
nostr-tools ~200KB (served locally)
NOSTR_LOGIN_LITE ~50KB (gzipped)
Total: ~250KB
vs.
Full nostr-login: ~2.5MB+ framework dependencies
Future Roadmap ⚠️
The following features are planned but not yet implemented:
- NIP-46 Connect: External signer integration
- OTP/DM: Server-side OTP delivery
- Connect Wallet: Wallet integration
- Advanced UI: Multi-screen flows
- NIP-05 Profiles: User discovery
- Backup/Restore: Key backup functionality
Development
⚠️ CRITICAL: DO NOT EDIT nostr-lite.js DIRECTLY!
The nostr-lite.js file is auto-generated by the build script. All changes must be made in the build script itself.
Build Process
# The main library source code is in:
lite/build.js # ← Edit this file for library changes
# To make changes:
1. Edit lite/build.js # Contains all source code
2. cd lite && node build.js # Regenerates nostr-lite.js
3. Test your changes in examples/
# NEVER edit these files directly (they get overwritten):
lite/nostr-lite.js # ← Auto-generated, don't edit!
# Separate components that can be edited:
lite/ui/modal.js # Modal UI component
themes/default/theme.css # Default theme
themes/dark/theme.css # Dark theme
Development Workflow
# 1. Make changes to source
nano lite/build.js
# 2. Rebuild bundle
cd lite && node build.js
# 3. Start dev server (from project root)
python3 -m http.server 8000
# 4. Test changes
open http://localhost:8000/examples/modal.html
Local Bundle Setup
The project uses a local copy of nostr-tools:
lite/nostr.bundle.js- Local nostr-tools bundle (serves from this location)nostr-tools/- Reference directory (excluded from git, not used in runtime)- Examples load from:
../lite/nostr.bundle.js
Examples
See examples/ directory:
simple-demo.html- Basic functionality demofull-test.html- Comprehensive test suitetest-lite.html- Minimal functionality test
Migration from Full nostr-login
The lite version provides the same API surface, but is much smaller:
// Before (full library)
import { init, launch, logout } from 'nostr-login';
// After (lite version)
await window.NOSTR_LOGIN_LITE.init();
window.NOSTR_LOGIN_LITE.launch();
window.NOSTR_LOGIN_LITE.logout();
License
Same license as the original nostr-login project.
Contributing
This is meant to be lightweight and focused. Contributions should maintain the minimal footprint while extending functionality.