Introduction

I'm thrilled to introduce PushForge v1.0.0, my latest open-source contribution to the web development ecosystem. PushForge is a zero-dependency toolkit designed to make Web Push Notifications implementation seamless across multiple platforms including Node.js, Browsers, Deno, Bun, and even Cloudflare Workers.

Why I Built PushForge ❓

When my team needed push notifications for a project, we discovered existing libraries were unnecessarily heavy and restrictive, especially for edge computing environments. This constraint led us to develop a custom solution, which eventually inspired me to create a more comprehensive package with broader compatibility.

PushForge addresses these challenges by providing:

  • A lightweight solution with zero external dependencies
  • Cross-platform compatibility for modern JavaScript environments
  • TypeScript-first development for robust applications
  • Complete control over the notification process

🔑 Key Features

Cross-Platform Compatibility

PushForge works seamlessly across multiple environments:

  • Node.js (v16+)
  • Web Browsers
  • Deno
  • Bun
  • Cloudflare Workers

This versatility ensures that regardless of your tech stack, you can implement push notifications without platform-specific workarounds.

Zero Dependencies

PushForge is engineered to be lightweight and self-contained, making it especially valuable for edge computing environments where bundle size is critical. By eliminating external dependencies, we reduce potential security vulnerabilities and ensure a smaller footprint in your projects.

TypeScript-First Design

The entire library is built with TypeScript, providing comprehensive type definitions out of the box. This approach delivers:

  • Improved developer experience with autocomplete suggestions
  • Type safety to catch errors during development
  • Better documentation through type annotations

Complete VAPID Authentication & Web Push Protocol Support

PushForge implements the full Web Push Protocol specification, ensuring your notifications are secure and compatible with all modern browsers.

⚙️ Technical Deep Dive

Web Push Protocol Implementation

PushForge implements several critical components of the Web Push Protocol:

VAPID Authentication (JWT with ES256)

PushForge uses the ES256 algorithm (ECDSA using P-256 curve and SHA-256 hash) to create and verify JSON Web Tokens (JWTs) for Voluntary Application Server Identification (VAPID). This process:

  1. Generates a JWT using the server's private key
  2. Signs it with the ES256 algorithm
  3. Includes the server's contact information
  4. Sets appropriate expiration times (up to 24 hours)

The resulting authorization header allows push services to validate that your server is authorized to send notifications to the user.

ECDH Key Exchange

Elliptic Curve Diffie-Hellman (ECDH) key exchange enables secure communication between your server and the user's browser:

  1. The browser generates a public/private key pair during subscription
  2. Your server receives the public key (p256dh)
  3. PushForge uses ECDH to create a shared secret using your server's generated key pair and the user's public key
  4. This shared secret becomes the basis for encryption

HKDF Key Derivation

HMAC-based Key Derivation Function (HKDF) transforms the shared ECDH secret into appropriate encryption keys:

  1. Combines the shared secret with the authentication secret (auth) provided by the browser
  2. Uses a salt value (randomly generated for each message)
  3. Derives encryption key and nonce (initialization vector) for AES-GCM

AES-GCM Encryption

Advanced Encryption Standard with Galois/Counter Mode (AES-GCM):

  1. Encrypts the notification payload using the derived encryption key
  2. Provides authenticated encryption (data integrity and confidentiality)
  3. Incorporates appropriate padding to obscure message length
  4. Outputs the encrypted content ready for transmission

Compliant Implementation Details

PushForge follows RFC 8291 (Message Encryption for Web Push) standards, ensuring:

  • Content-Encoding: aes128gcm format
  • Proper salt generation and record size limits
  • Correct padding implementation
  • Authentication tag handling

⚒️ Development Workflow

PushForge employs modern development tools to ensure code quality and streamlined contributions:

Semantic Release

Automated versioning and changelog generation based on conventional commit messages, which:

  • Determines version numbers automatically (major, minor, patch)
  • Generates detailed release notes
  • Publishes updates to npm when merging to main branch

GitHub Actions for CI/CD

Continuous integration and deployment pipelines that:

  • Run the test suite on every pull request
  • Verify code formatting and linting
  • Ensure type checking passes
  • Automate the release process

Biome for Code Quality

Biome provides fast, modern formatting and linting:

  • Enforces consistent code style
  • Catches potential bugs early
  • Runs as part of pre-commit checks

Testing with Vitest

Comprehensive test coverage using Vitest:

  • Unit tests for core functionality
  • Integration tests for different environments
  • Fast execution through Vite's architecture

Project Management with Linear

Linear helps track issues and plan development:

  • Manages the feature roadmap
  • Coordinates sprint planning
  • Keeps issue backlog organized
  • Integrates with GitHub for streamlined workflow

💡 When to Use PushForge

PushForge is particularly well-suited for projects that require:

  • Edge Computing Compatibility: Deploy to serverless or edge environments without worry about dependencies or platform limitations.
  • TypeScript Projects: Benefit from full type safety and improved developer experience.
  • Custom Push Logic: Implement complex notification strategies with full control over the process.
  • Cross-Platform Solutions: Build unified notification systems that work across different JavaScript environments.

📈 Future Plans

I'm actively working on expanding PushForge with these planned features:

Batching & Queuing System

  • Efficient bulk notification delivery
  • Rate limiting and automatic retry mechanisms
  • Priority-based queuing

Built-in Request Functionality

  • Currently, you provide your own fetch implementation
  • Future versions will include built-in request handling
  • Support for automatic error handling and retries

Legacy GCM Support

  • Backward compatibility for older notification systems
  • Support for Google Cloud Messaging legacy endpoints

Comprehensive Examples

  • Ready-to-use examples for popular frameworks (React, Vue, Angular, etc.)
  • Server-side implementations for Node.js, Express, Fastify, etc.
  • Service worker templates for quick implementation

Getting Started with PushForge

Here's a quick guide to implementing PushForge in your project:

Step 1: Installation

Choose your preferred package manager:

# NPM
npm install @pushforge/builder

# Yarn
yarn add @pushforge/builder

# pnpm
pnpm add @pushforge/builder

Step 2: Generate VAPID Keys

Use the built-in CLI tool to generate your VAPID keys:

npx @pushforge/builder generate-vapid-keys

This will output a public key and private key that you'll use for authentication.

Step 3: Send Notifications from Your Server

import { buildPushHTTPRequest } from "@pushforge/builder";

// Load the private key from your secure environment
const privateJWK = process.env.VAPID_PRIVATE_KEY;

// User subscription from browser push API
const subscription = {
  endpoint: "https://fcm.googleapis.com/fcm/send/DEVICE_TOKEN",
  keys: {
    p256dh: "USER_PUBLIC_KEY",
    auth: "USER_AUTH_SECRET",
  },
};

// Create message with payload
const message = {
  payload: {
    title: "New Message",
    body: "You have a new message!",
    icon: "/images/icon.png",
  },
  options: {
    ttl: 3600, // Time-to-live in seconds
    urgency: "normal", // Options: "very-low", "low", "normal", "high"
    topic: "updates", // Optional topic for replacing notifications
  },
  adminContact: "mailto:[email protected]", // Contact information
};

// Build the push notification request
const { endpoint, headers, body } = await buildPushHTTPRequest({
  privateJWK,
  message,
  subscription,
});

// Send the push notification
const response = await fetch(endpoint, {
  method: "POST",
  headers,
  body,
});

🫂 Join the Community

Contributions to PushForge are welcome and encouraged! The project follows a structured workflow for contributions as outlined in the Contributing Guidelines.

Whether you want to:

  • Report bugs or suggest features
  • Improve tests or documentation
  • Submit pull requests

Here's how to contribute:

  1. Create an issue in the GitHub tracker describing your proposed change
  2. Wait for a Linear issue number to be assigned
  3. Fork the repository and create a branch with the proper naming convention:
username/wpn-issuenumber-issuetitle
  1. Make your changes following our commit guidelines
  2. Submit a pull request linking to the issue

Let's build the best push notification solution together! 💪

📖 References

My work on PushForge was informed by these key resources:


I'm excited to see what you'll build with PushForge! Feel free to star the repository, open issues, or reach out with questions. Together, we can make web push notifications simpler and more accessible for developers everywhere.