authia 0.3.4

High-performance JWT verification library for Ed25519 using WebAssembly
Documentation
# authia


[English]./README.md | [日本語]./README.ja.md

High-performance JWT verification library for Ed25519 using WebAssembly.

## Features


- 🚀 Fast Ed25519 JWT verification using Rust + WebAssembly
-**v0.3.0 Optimization**: Single-pass JSON parsing for maximum performance
- 🔒 Secure by design - algorithm fixed to Ed25519
- 🌐 Universal runtime support (Node.js, Browser, Cloudflare Workers)
- 📦 Zero runtime dependencies
- 🎯 TypeScript type definitions included
- ⚡ Automatic Wasm initialization

## 📊 Benchmarks


Performance varies significantly by runtime environment:

**Cloudflare Workers / Edge Runtimes:**

| Library           | Avg (ms)   | p50 (ms)   | p95 (ms)   |
| :---------------- | :--------- | :--------- | :--------- |
| **authia (WASM)** | **0.20ms** | **0.17ms** | **0.36ms** |
| jose (WebCrypto)  | 0.30ms     | 0.28ms     | 0.50ms     |

**Node.js (native crypto):**

| Library       | Avg (ms)           |
| :------------ | :----------------- |
| jose (native) | **0.01-0.03ms**|
| authia (WASM) | 0.17-0.20ms        |

_In Node.js, jose uses native C++ crypto bindings and is significantly faster. authia is optimized for edge runtimes where both libraries use similar APIs._

## Installation


```bash
npm install authia
```

## Usage


The library automatically detects the environment (Node.js or Bundler/Workers) and handles WebAssembly loading.

### Access Token Verification


```typescript
import { verifyAccessToken } from "authia";

try {
  // ⚡ RECOMMENDED: Use publicKeyJwkRaw for better performance (v0.2.0+)
  const payload = await verifyAccessToken(token, {
    publicKeyJwkRaw: process.env.JWT_PUBLIC_KEY, // Raw JWK JSON string
    audience: "kapock-app",
    issuer: "https://auth.kapock.com",
  });

  console.log(`User ID: ${payload.sub}, Email: ${payload.email}`);
} catch (error) {
  console.error("Token verification failed:", error);
}
```

**Legacy (still supported, but slower):**

```typescript
// Base64-encoded JWK (backward compatible)
const payload = await verifyAccessToken(token, {
  publicKeyJwk: btoa(process.env.JWT_PUBLIC_KEY), // Requires base64 encoding
  audience: "kapock-app",
  issuer: "https://auth.kapock.com",
});
```

### Refresh Token Verification


```typescript
import { verifyRefreshToken } from "authia";

const payload = await verifyRefreshToken(token, {
  publicKeyJwkRaw: process.env.JWT_PUBLIC_KEY, // Use raw JWK for better performance
  audience: "kapock-app",
  issuer: "https://auth.kapock.com",
});

console.log(`JTI: ${payload.jti}`);
```

### Performance Tips


1. **Use `publicKeyJwkRaw`** instead of `publicKeyJwk` (2-5x faster in high-throughput scenarios)
2. **Cache your verification options** at the worker/process level
3. The library automatically caches the decoded public key internally

```typescript
// Worker-level caching example (Cloudflare Workers)
let cachedPublicKey: string | null = null;

export async function verifyToken(token: string, env: Env) {
  if (!cachedPublicKey) {
    cachedPublicKey = env.JWT_PUBLIC_KEY.trim();
  }

  return verifyAccessToken(token, {
    publicKeyJwkRaw: cachedPublicKey, // Avoid repeated trim() calls
    audience: "kapock-app",
    issuer: "https://auth.kapock.com",
  });
}
```

## Runtime Behavior


### Node.js


Verification is **synchronous**. The WebAssembly module is loaded and instantiated at startup using the optimized Node.js target.

### Cloudflare Workers / Bundlers


Verification is also **synchronous**. The library automatically handles WebAssembly instantiation during module load. The `await` in examples is supported but not strictly required for the verification itself (it returns the payload directly).

## API


See [API Documentation](./docs/api.md) for detailed information.

## Known Issues & Limitations


⚠️ **Important Notes for Production Use**

### Performance Considerations


**Node.js Environments:**

- authia has a **JS ↔ WASM boundary overhead** of ~0.1-0.15ms per call
- The popular `jose` library uses native C++ crypto bindings and is typically **faster in Node.js** (0.01-0.03ms)
- **Recommendation**: For Node.js backends, consider using `jose` instead of authia

**Cloudflare Workers / Edge Runtimes:**

- authia performs **competitively** in these environments where `jose` also uses WebCrypto APIs
- The WASM approach provides **consistent performance** across different edge platforms
- **Recommendation**: authia is well-suited for Cloudflare Workers with Ed25519 tokens

### Schema Validation (v0.3.x)


- **Strict schema validation**: v0.3.1-v0.3.3 use strict type checking for JWT claims
- Missing optional fields (like `email`) may cause verification to fail
- **Workaround**: Ensure all tokens include expected fields, or use v0.2.x for more lenient parsing
- **Future improvement**: Planned migration to flexible schema with `Option<T>` types

### Environment Variable Parsing


- Public key format detection: The library attempts to auto-detect JSON vs Base64-encoded JWK
- **Best practice**: Use raw JSON format for `publicKeyJwkRaw` option (recommended)
- If using Base64, ensure proper encoding without PEM headers

### Recommended Use Cases


✅ **Good fit:**

- Cloudflare Workers with Ed25519 JWT tokens
- Edge runtimes requiring consistent cross-platform behavior
- Learning Rust + WebAssembly development

❌ **Consider alternatives:**

- Node.js backends with high-throughput requirements → use `jose`
- Tokens with varying claim structures → use v0.2.x or `jose`
- Production systems requiring maximum stability → use `jose`

## License


MIT