Gleam Web Push
The first and complete Web Push notification library for Gleam! π
Send encrypted push notifications to web browsers using the Web Push Protocol (RFC 8291) with full VAPID (RFC 8292) support.
β¨ Features
- π RFC 8291 compliant encryption with AES-128-GCM
- π VAPID authentication (RFC 8292) with ES256 JWT signing
- π― Complete Web Push API support (TTL, urgency, topics)
- π‘οΈ Type-safe error handling with comprehensive error types
- β‘ High performance with Erlang FFI for cryptographic operations
- π¦ Zero external dependencies (uses built-in Erlang crypto)
- π§ Easy to use with sensible defaults
π Quick Start
Installation
Add webpush
to your project:
gleam add webpush@1
Basic Usage
Generate Keys
Using the library to generate VAPID keys:
Note: Do this once and store the keys securely.
import gleam/io
import webpush/vapid
pub fn main() {
// Generate VAPID keys (do this once, store securely)
let assert Ok(keys) = vapid.generate_vapid_keys()
io.println("VAPID keys generated successfully!")
io.println("Public Key: " <> keys.public_key_b64url)
io.println("Private Key: " <> keys.private_key_b64url)
}
Send Notification
Using the library to send a push notification:
import gleam/bit_array
import gleam/io
import gleam/option
import webpush/push
import webpush/urgency
pub fn main() {
// 2. Create subscription (from your frontend)
let subscription =
push.Subscription(
endpoint: "https://fcm.googleapis.com/fcm/send/...",
keys: push.Keys(
auth: "authentication_secret_from_browser",
p256dh: "user_public_key_from_browser",
),
)
// 3. Configure push options
let options =
push.Options(
ttl: 3600,
// 1 hour
subscriber: "mailto:your-email@example.com",
// Your contact info
vapid_public_key_b64url: "YOUR_PUBLIC_KEY",
vapid_private_key_b64url: "YOUR_PRIVATE_KEY",
topic: option.Some("updates"),
urgency: option.Some(urgency.Normal),
record_size: option.None,
// Use default (4096)
vapid_expiration_unix: option.None,
// Use default (12h)
)
// 4. Create your message
let payload =
"{\"title\":\"Hello from Gleam!\",\"body\":\"Your notification message\"}"
let message = bit_array.from_string(payload)
// 5. Send the notification
case push.send_notification(message, subscription, options) {
Ok(_) -> {
// Success! Check response.status for HTTP status code
io.println("Notification sent successfully!")
}
Error(error) -> {
// Handle error
io.println("Failed to send: " <> push.push_error_to_string(error))
}
}
}
π API Documentation
Key Functions
push.send_notification
Send a push notification:
pub fn send_notification(
message: BitArray,
subscription: Subscription,
options: Options
) -> Result(response.Response(BitArray), PushError)
vapid.generate_vapid_keys
Generate new VAPID key pair:
pub fn generate_vapid_keys() -> Result(VapidKeys, VapidError)
ποΈ Architecture
This library uses Erlang FFI for performance-critical cryptographic operations:
- P-256 ECDH for key agreement
- HKDF for key derivation (RFC 5869)
- AES-128-GCM for payload encryption
- ES256 JWT signing for VAPID authentication
The Gleam layer provides type safety and ergonomic APIs while leveraging Erlangβs battle-tested crypto implementations.
Development
gleam run # Run the project
gleam test # Run the tests
π€ Contributing
Contributions are welcome! Please feel free to submit issues, feature requests, or pull requests.
π License
This project is licensed under the MIT License - see the LICENSE file for details.
π Acknowledgments
- Built following RFC 8291 (Web Push Encryption)
- VAPID implementation per RFC 8292
- Inspired by web push libraries in other languages
Made with β¨ by the Gleam community
This is the first Web Push library for Gleam - help us make it even better!
Further documentation can be found at https://hexdocs.pm/webpush.