# Gleam Web Push
[](https://hex.pm/packages/webpush)
[](https://hexdocs.pm/webpush/)
[](https://github.com/your-username/gleam_webpush/blob/main/LICENSE)
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:
```sh
gleam add webpush@1
```
### Basic Usage
#### Generate Keys
Using the library to generate VAPID keys:
> Note: Do this once and store the keys securely.
```gleam
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:
```gleam
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:
```gleam
pub fn send_notification(
message: BitArray,
subscription: Subscription,
options: Options
) -> Result(response.Response(BitArray), PushError)
```
#### `vapid.generate_vapid_keys`
Generate new VAPID key pair:
```gleam
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
```sh
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](LICENSE) file for details.
## 🙏 Acknowledgments
- Built following [RFC 8291](https://tools.ietf.org/html/rfc8291) (Web Push Encryption)
- VAPID implementation per [RFC 8292](https://tools.ietf.org/html/rfc8292)
- 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>.