npm package: @periodic/tungsten
Description: Production-grade, security-auditable authentication primitives for Node.js with TypeScript support
Author: Uday Thakur
Latest version: 1.0.0

# 🔩 Periodic Tungsten

[![npm version](https://img.shields.io/npm/v/@periodic/tungsten.svg)](https://www.npmjs.com/package/@periodic/tungsten)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
[![TypeScript](https://img.shields.io/badge/TypeScript-5.3-blue)](https://www.typescriptlang.org/)

**Production-grade, security-auditable authentication primitives for Node.js with TypeScript support**

Part of the **Periodic** series of Node.js packages by Uday Thakur.

---

## 💡 Why Tungsten?

**Tungsten** gets its name from the chemical element renowned for having the highest melting point of all metals — it holds its structure under conditions that destroy everything else. In engineering, tungsten is the material you reach for when the environment is too extreme for anything less. Just like tungsten performs where other materials fail, this library **handles authentication under conditions where a mistake means a breach**.

In chemistry, tungsten forms exceptionally strong carbide compounds used in cutting tools and armour-piercing projectiles — its strength comes not from softness or flexibility, but from density and resistance to deformation. Similarly, **@periodic/tungsten** is uncompromising: constant-time comparisons, memory-hard hashing, cryptographically secure generation, and no shortcuts.

The name represents:
- **Hardness**: Cryptographic primitives that don't bend under attack
- **Precision**: Every operation is explicit — no magic, no hidden configuration
- **Durability**: Secure defaults that remain correct over time and key rotation
- **Purity**: No framework coupling, no database assumptions, no transport opinions

Just as tungsten is the material engineers trust in the most demanding environments, **@periodic/tungsten** is the authentication layer you trust when the cost of failure is highest.

---

## 🎯 Why Choose Tungsten?

Authentication is one of the most common sources of critical security vulnerabilities — and most implementations get the subtle parts wrong:

- **DIY JWT libraries** miss `issuer` and `audience` validation, opening the door to token confusion attacks
- **bcrypt** is showing its age — Argon2id is the current OWASP recommendation and tungsten uses it by default
- **API key generation** with `Math.random()` or weak entropy is endemic in backend codebases
- **No refresh token rotation** means stolen tokens are valid forever
- **Timing-unsafe comparisons** in API key and HMAC verification leak information to attackers
- **No key rotation support** means rotating credentials requires a deployment instead of a config change

**Periodic Tungsten** provides the perfect solution:

✅ **Zero framework dependencies** — works with Express, Fastify, Koa, or no framework at all  
✅ **JWT Access & Refresh Tokens** — HS256 and RS256 with key rotation built in  
✅ **Argon2id Password Hashing** — OWASP-recommended defaults, constant-time verification  
✅ **API Key Generation** — cryptographically secure with prefix support  
✅ **Opaque Tokens** — session identifier generation  
✅ **TOTP (RFC 6238)** — time-based one-time passwords for 2FA  
✅ **HMAC Request Signing** — webhook verification with replay protection  
✅ **Cookie Utilities** — secure configuration helpers  
✅ **Multi-Tenant Key Abstraction** — enterprise key management  
✅ **Key Rotation** — add, retire, and switch signing keys without downtime  
✅ **Type-safe** — strict TypeScript throughout, zero `any`  
✅ **Tree-shakeable** — ESM + CJS, import only what you use  
✅ **No global state** — no side effects on import  
✅ **Production-ready** — timing-safe, entropy-safe, no secret leakage

---

## 📦 Installation

```bash
npm install @periodic/tungsten
```

Or with yarn:

```bash
yarn add @periodic/tungsten
```

---

## 🚀 Quick Start

```typescript
import {
  signAccessToken,
  verifyAccessToken,
  hashPassword,
  verifyPassword,
  generateApiKey,
  SimpleKeyProvider,
} from '@periodic/tungsten';

// JWT
const keyProvider = new SimpleKeyProvider('your-secret-key-min-32-chars', 'HS256');
const token = await signAccessToken({ sub: 'user_123', role: 'admin' }, {
  expiresIn: '15m',
  issuer: 'api.example.com',
  audience: 'dashboard',
  keyProvider,
});
const payload = await verifyAccessToken(token, { keyProvider, issuer: 'api.example.com', audience: 'dashboard' });

// Password
const hash = await hashPassword('MySecurePassword123!');
const isValid = await verifyPassword('MySecurePassword123!', hash);

// API Key
const apiKey = generateApiKey({ prefix: 'sk_live_' }); // sk_live_xYz123...
```

**Example token payload:**

```json
{
  "sub": "user_123",
  "role": "admin",
  "iss": "api.example.com",
  "aud": "dashboard",
  "iat": 1708000000,
  "exp": 1708000900,
  "jti": "01HQ4K2N..."
}
```

---

## 🧠 Core Concepts

### Key Providers

- **Key providers are the central abstraction** — they decouple signing keys from the functions that use them
- `SimpleKeyProvider` for single-tenant, single-key setups
- `RotatingKeyProvider` for production systems that need to retire old keys without downtime
- **Pass the provider at call time** — no global state, safe for multi-tenant apps

```typescript
// Single key
const provider = new SimpleKeyProvider('your-secret-key', 'HS256');

// Key rotation — sign with new key, verify with old and new
const provider = new RotatingKeyProvider({
  kid: process.env.CURRENT_KEY_ID,
  secret: process.env.CURRENT_KEY_SECRET,
  algorithm: 'HS256',
});
provider.addKey(process.env.OLD_KEY_ID, process.env.OLD_KEY_SECRET, 'HS256');
```

### Security Model

**Design principle:**
> Every function is explicit. Nothing reads from `process.env`, nothing has global configuration, nothing silently falls back to insecure defaults. If a parameter is required for security, it is required by the type system.

- All comparisons are timing-safe — no early exits that leak information
- All generation uses `crypto.randomBytes` — no `Math.random()`
- All hashing uses Argon2id with OWASP-recommended parameters
- All JWT verification validates `issuer` and `audience` when provided

---

## ✨ Features

### 🔑 JWT Access & Refresh Tokens

Sign and verify tokens with HS256 or RS256, with key rotation and refresh token replay detection:

```typescript
import { signAccessToken, verifyAccessToken, rotateRefreshToken } from '@periodic/tungsten';

// Sign
const token = await signAccessToken({ sub: 'user_123' }, {
  expiresIn: '15m',
  issuer: 'api.example.com',
  audience: 'dashboard',
  keyProvider,
});

// Verify
const payload = await verifyAccessToken(token, {
  keyProvider,
  issuer: 'api.example.com',
  audience: 'dashboard',
  clockTolerance: 60, // seconds
});

// Rotate refresh token with replay detection
const result = await rotateRefreshToken(oldToken, {
  keyProvider,
  onTokenReused: async (jti) => {
    logger.warn('Token reuse detected — revoking all sessions', { jti });
    await revokeAllUserSessions(jti);
  },
});
```

### 🔒 Password Hashing

Argon2id with OWASP-recommended defaults and constant-time verification:

```typescript
import { hashPassword, verifyPassword } from '@periodic/tungsten';

const hash = await hashPassword('MySecurePassword123!');
// Defaults: 64MB memory, 3 iterations, parallelism 4

const isValid = await verifyPassword('MySecurePassword123!', hash);
// Constant-time — safe against timing attacks
```

### 🗝️ API Key Generation

Cryptographically secure generation with timing-safe verification:

```typescript
import { generateApiKey, hashApiKey, verifyApiKey } from '@periodic/tungsten';

const apiKey = generateApiKey({ prefix: 'sk_live_', length: 32 });
// sk_live_xYz123... (crypto.randomBytes, min 16-byte entropy enforced)

const hash = hashApiKey(apiKey); // SHA-256, store this
const isValid = verifyApiKey(apiKey, hash); // timing-safe comparison
```

### 🔐 TOTP (Two-Factor Authentication)

RFC 6238 compliant, compatible with Google Authenticator and Authy:

```typescript
import { generateTOTPSecret, generateTOTP, verifyTOTP } from '@periodic/tungsten';

const secret = generateTOTPSecret(); // show QR code to user
const code = generateTOTP(secret, { period: 30, digits: 6 });

const result = verifyTOTP(userProvidedCode, secret, { window: 1 });
if (result.valid) {
  console.log('2FA verified');
}
```

### ✍️ HMAC Request Signing

Webhook payload signing with replay protection:

```typescript
import { signPayload, verifySignature } from '@periodic/tungsten';

const signature = signPayload({ event: 'user.created', userId: '123' }, 'webhook-secret');
const isValid = verifySignature(payload, signature, 'webhook-secret');
// Validates timestamp — rejects requests older than 5 minutes by default
```

### 🍪 Cookie Utilities

Secure cookie configuration helpers:

```typescript
import { getSecureCookieOptions } from '@periodic/tungsten';

const options = getSecureCookieOptions({ 
  maxAge: 15 * 60, // 15 minutes
  sameSite: 'strict',
});
// httpOnly: true, secure: true, sameSite: 'strict' — safe defaults
```

### 🏢 Key Rotation

Add, retire, and switch signing keys without downtime:

```typescript
import { RotatingKeyProvider } from '@periodic/tungsten';

const provider = new RotatingKeyProvider({
  kid: 'key-2025-01',
  secret: process.env.KEY_2025_01,
  algorithm: 'HS256',
});

// Add new key — start signing with it
provider.addKey('key-2025-02', process.env.KEY_2025_02, 'HS256');
provider.setCurrentKey('key-2025-02');

// Old key stays registered for verifying tokens still in circulation
// Remove it once all old tokens have expired
```

---

## 📚 Common Patterns

### 1. Authentication Middleware

```typescript
import { verifyAccessToken, SimpleKeyProvider } from '@periodic/tungsten';

const keyProvider = new SimpleKeyProvider(process.env.JWT_SECRET, 'HS256');

export async function authMiddleware(req, res, next) {
  const token = req.headers.authorization?.replace('Bearer ', '');
  if (!token) return res.status(401).json({ error: 'Missing token' });

  try {
    const payload = await verifyAccessToken(token, {
      keyProvider,
      issuer: process.env.JWT_ISSUER,
      audience: process.env.JWT_AUDIENCE,
    });
    req.user = payload;
    next();
  } catch {
    res.status(401).json({ error: 'Invalid token' });
  }
}
```

### 2. Registration and Login

```typescript
import { hashPassword, verifyPassword, signAccessToken } from '@periodic/tungsten';

async function register(email: string, password: string) {
  const hash = await hashPassword(password);
  await db.users.create({ email, passwordHash: hash });
}

async function login(email: string, password: string) {
  const user = await db.users.findOne({ email });
  const isValid = await verifyPassword(password, user.passwordHash);
  if (!isValid) throw new Error('Invalid credentials');

  return signAccessToken({ sub: user.id, role: user.role }, {
    expiresIn: '15m',
    keyProvider,
  });
}
```

### 3. Refresh Token Rotation

```typescript
import { rotateRefreshToken } from '@periodic/tungsten';

app.post('/auth/refresh', async (req, res) => {
  try {
    const result = await rotateRefreshToken(req.cookies.refresh_token, {
      keyProvider,
      onTokenReused: async (jti) => {
        logger.warn('Refresh token reuse — possible theft', { jti });
        await db.sessions.revokeAll({ jti });
      },
    });

    res.cookie('refresh_token', result.newToken, getSecureCookieOptions({ maxAge: 7 * 24 * 60 * 60 }));
    res.json({ accessToken: result.accessToken });
  } catch {
    res.status(401).json({ error: 'Invalid refresh token' });
  }
});
```

### 4. API Key Issuance and Verification

```typescript
import { generateApiKey, hashApiKey, verifyApiKey } from '@periodic/tungsten';

// Issuance — show the plain key once, store only the hash
async function issueApiKey(userId: string) {
  const apiKey = generateApiKey({ prefix: 'sk_live_' });
  const hash = hashApiKey(apiKey);
  await db.apiKeys.create({ userId, hash, createdAt: new Date() });
  return apiKey; // return to user once — never stored
}

// Verification
async function verifyApiKeyRequest(providedKey: string) {
  const keys = await db.apiKeys.findAll();
  return keys.find(k => verifyApiKey(providedKey, k.hash));
}
```

### 5. TOTP Enrollment and Verification

```typescript
import { generateTOTPSecret, verifyTOTP } from '@periodic/tungsten';
import QRCode from 'qrcode';

async function enrollTOTP(userId: string) {
  const secret = generateTOTPSecret();
  await db.users.update({ userId }, { totpSecret: secret, totpEnabled: false });

  const otpAuthUrl = `otpauth://totp/MyApp:${userId}?secret=${secret}&issuer=MyApp`;
  const qrCode = await QRCode.toDataURL(otpAuthUrl);
  return { secret, qrCode };
}

async function verifyAndActivateTOTP(userId: string, code: string) {
  const user = await db.users.findOne({ userId });
  const result = verifyTOTP(code, user.totpSecret);
  if (!result.valid) throw new Error('Invalid TOTP code');
  await db.users.update({ userId }, { totpEnabled: true });
}
```

### 6. Webhook Signing and Verification

```typescript
import { signPayload, verifySignature } from '@periodic/tungsten';

// Signing outbound webhooks
async function sendWebhook(url: string, event: object) {
  const signature = signPayload(event, process.env.WEBHOOK_SECRET);
  await fetch(url, {
    method: 'POST',
    headers: { 'X-Signature': signature, 'Content-Type': 'application/json' },
    body: JSON.stringify(event),
  });
}

// Verifying inbound webhooks
app.post('/webhooks/stripe', (req, res) => {
  const isValid = verifySignature(req.body, req.headers['x-signature'], process.env.WEBHOOK_SECRET);
  if (!isValid) return res.status(401).json({ error: 'Invalid signature' });
  // process event
  res.sendStatus(200);
});
```

### 7. Structured Logging Integration

```typescript
import { createLogger, ConsoleTransport, JsonFormatter } from '@periodic/iridium';
import { rotateRefreshToken } from '@periodic/tungsten';

const logger = createLogger({
  transports: [new ConsoleTransport({ formatter: new JsonFormatter() })],
});

await rotateRefreshToken(oldToken, {
  keyProvider,
  onTokenReused: async (jti) => {
    logger.warn('tungsten.token_reuse', { jti, severity: 'high' });
    await revokeAllUserSessions(jti);
  },
});
```

### 8. Production Configuration

```typescript
import {
  RotatingKeyProvider,
  signAccessToken,
  verifyAccessToken,
  hashPassword,
  verifyPassword,
} from '@periodic/tungsten';

const keyProvider = new RotatingKeyProvider({
  kid: process.env.JWT_KEY_ID,
  secret: process.env.JWT_KEY_SECRET,
  algorithm: 'HS256',
});

// Register previous key for tokens still in circulation
if (process.env.JWT_PREV_KEY_ID) {
  keyProvider.addKey(process.env.JWT_PREV_KEY_ID, process.env.JWT_PREV_KEY_SECRET, 'HS256');
}

export const auth = {
  sign: (payload: object) =>
    signAccessToken(payload, {
      expiresIn: '15m',
      issuer: process.env.JWT_ISSUER,
      audience: process.env.JWT_AUDIENCE,
      keyProvider,
    }),

  verify: (token: string) =>
    verifyAccessToken(token, {
      keyProvider,
      issuer: process.env.JWT_ISSUER,
      audience: process.env.JWT_AUDIENCE,
      clockTolerance: 60,
    }),

  hashPassword,
  verifyPassword,
};

export default auth;
```

---

## 🎛️ Configuration Options

### `signAccessToken` Options

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `keyProvider` | `KeyProvider` | required | Key provider instance |
| `expiresIn` | `string \| number` | required | Expiration (e.g. `'15m'`, `'1h'`) |
| `issuer` | `string` | — | Token issuer (`iss` claim) |
| `audience` | `string \| string[]` | — | Token audience (`aud` claim) |
| `kid` | `string` | — | Key ID override for rotation |

### `verifyAccessToken` Options

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `keyProvider` | `KeyProvider` | required | Key provider instance |
| `issuer` | `string` | — | Expected issuer (validated if provided) |
| `audience` | `string \| string[]` | — | Expected audience (validated if provided) |
| `clockTolerance` | `number` | `60` | Clock skew tolerance in seconds |

### `generateApiKey` Options

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `prefix` | `string` | — | Key prefix (e.g. `'sk_live_'`) |
| `length` | `number` | `32` | Key entropy in bytes (min: 16) |

### `generateTOTP` / `verifyTOTP` Options

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `period` | `number` | `30` | Time step in seconds |
| `digits` | `number` | `6` | Code length |
| `algorithm` | `'SHA1' \| 'SHA256' \| 'SHA512'` | `'SHA1'` | Hash algorithm |
| `window` | `number` | `1` | Verification tolerance window |

### `RotatingKeyProvider`

| Method | Description |
|--------|-------------|
| `addKey(kid, secret, algorithm)` | Register an additional key for verification |
| `setCurrentKey(kid)` | Switch signing to a different registered key |

---

## 📋 API Reference

### JWT

```typescript
signAccessToken(payload: JWTPayload, options: SignAccessTokenOptions): Promise<string>
verifyAccessToken(token: string, options: VerifyAccessTokenOptions): Promise<JWTPayload>
rotateRefreshToken(oldToken: string, options: RotateRefreshTokenOptions): Promise<RefreshTokenRotationResult>
```

### Password

```typescript
hashPassword(password: string): Promise<string>
verifyPassword(password: string, hash: string): Promise<boolean>
```

### API Keys

```typescript
generateApiKey(options?: GenerateApiKeyOptions): string
hashApiKey(apiKey: string): string
verifyApiKey(apiKey: string, hash: string): boolean
```

### TOTP

```typescript
generateTOTPSecret(): string
generateTOTP(secret: string, options?: TOTPOptions): string
verifyTOTP(code: string, secret: string, options?: TOTPOptions): TOTPVerificationResult
```

### HMAC

```typescript
signPayload(payload: unknown, secret: string): string
verifySignature(payload: unknown, signature: string, secret: string): boolean
```

### Key Providers

```typescript
new SimpleKeyProvider(secret: string, algorithm: Algorithm, kid?: string): KeyProvider
new RotatingKeyProvider(primaryKey: KeyConfig): KeyProvider
```

### Types

```typescript
import type {
  JWTPayload,
  KeyProvider,
  SignAccessTokenOptions,
  VerifyAccessTokenOptions,
  GenerateApiKeyOptions,
  TOTPOptions,
  TOTPVerificationResult,
  RefreshTokenRotationResult,
} from '@periodic/tungsten';
```

---

## 🧩 Architecture

```
@periodic/tungsten/
├── src/
│   ├── jwt/
│   │   ├── sign.ts           # signAccessToken()
│   │   ├── verify.ts         # verifyAccessToken()
│   │   └── refresh.ts        # rotateRefreshToken() + replay detection
│   ├── password/
│   │   └── index.ts          # hashPassword(), verifyPassword() — Argon2id
│   ├── apikey/
│   │   └── index.ts          # generateApiKey(), hashApiKey(), verifyApiKey()
│   ├── totp/
│   │   └── index.ts          # generateTOTPSecret(), generateTOTP(), verifyTOTP()
│   ├── hmac/
│   │   └── index.ts          # signPayload(), verifySignature()
│   ├── cookies/
│   │   └── index.ts          # getSecureCookieOptions()
│   ├── keys/
│   │   ├── simple.ts         # SimpleKeyProvider
│   │   └── rotating.ts       # RotatingKeyProvider
│   ├── types.ts               # All shared TypeScript interfaces
│   └── index.ts               # Public API
```

**Design Philosophy:**
- **Primitives only** — no framework coupling, no database assumptions, no transport opinions
- **Explicit over implicit** — every security parameter is required or has a safe default
- **No global state** — all configuration is passed at call time
- **Timing-safe throughout** — no early exits in comparisons that could leak information
- **Key providers** decouple signing keys from the functions that use them — swap without changing call sites

---

## 📈 Performance

- **Argon2id** is intentionally slow for password hashing — that's the security property
- **JWT signing and verification** are async and non-blocking
- **API key generation** uses `crypto.randomBytes` — synchronous but fast
- **TOTP** verification is synchronous and sub-millisecond
- **No global state** — multiple instances in the same process are fully isolated
- **Tree-shakeable** — only the primitives you use end up in your bundle

---

## 🚫 Explicit Non-Goals

This package **intentionally does not** include:

❌ Session management or storage (bring your own database)  
❌ OAuth / OpenID Connect flows (use a dedicated OAuth library)  
❌ Framework middleware (adapt the primitives yourself)  
❌ User model or database schema (no opinions on your data layer)  
❌ Rate limiting (use `@periodic/titanium` for that)  
❌ HTTP transport (no `req`/`res` coupling)  
❌ Magic or implicit behavior on import  
❌ Configuration files (configure in code)

Focus on doing one thing well: **cryptographically sound, framework-agnostic authentication primitives**.

---

## 🎨 TypeScript Support

Full TypeScript support with complete type safety:

```typescript
import type {
  JWTPayload,
  KeyProvider,
  TOTPVerificationResult,
  RefreshTokenRotationResult,
} from '@periodic/tungsten';

// Generic payload — type flows through automatically
const payload = await verifyAccessToken<{ sub: string; role: 'admin' | 'user' }>(token, options);
payload.role; // typed as 'admin' | 'user'

// TOTPVerificationResult is discriminated
const result = verifyTOTP(code, secret);
if (result.valid) {
  result.delta; // number — present only when valid
}
```

---

## 🧪 Testing

```bash
# Run tests
npm test

# Run tests with coverage
npm run test:coverage

# Run tests in watch mode
npm run test:watch
```

**Note:** All tests achieve >80% code coverage.

---

## 🤝 Related Packages

Part of the **Periodic** series by Uday Thakur:

- [**@periodic/iridium**](https://www.npmjs.com/package/@periodic/iridium) - Structured logging
- [**@periodic/arsenic**](https://www.npmjs.com/package/@periodic/arsenic) - Semantic runtime monitoring
- [**@periodic/zirconium**](https://www.npmjs.com/package/@periodic/zirconium) - Environment configuration
- [**@periodic/vanadium**](https://www.npmjs.com/package/@periodic/vanadium) - Idempotency and distributed locks
- [**@periodic/strontium**](https://www.npmjs.com/package/@periodic/strontium) - Resilient HTTP client
- [**@periodic/obsidian**](https://www.npmjs.com/package/@periodic/obsidian) - HTTP error handling
- [**@periodic/titanium**](https://www.npmjs.com/package/@periodic/titanium) - Rate limiting
- [**@periodic/osmium**](https://www.npmjs.com/package/@periodic/osmium) - Redis caching

Build complete, production-ready APIs with the Periodic series!

---

## 📖 Documentation

- [Quick Start Guide](QUICKSTART.md)
- [Contributing Guide](CONTRIBUTING.md)
- [Changelog](CHANGELOG.md)

---

## 🛠️ Production Recommendations

### Key Management

Store signing keys in environment variables or a secrets manager — never hardcode them:

```bash
JWT_KEY_ID=key-2025-01
JWT_KEY_SECRET=your-256-bit-secret-here
JWT_PREV_KEY_ID=key-2024-12        # keep until old tokens expire
JWT_PREV_KEY_SECRET=previous-secret
JWT_ISSUER=api.example.com
JWT_AUDIENCE=dashboard
```

### Log Aggregation

Pair with `@periodic/iridium` for structured JSON output:

```typescript
import { createLogger, ConsoleTransport, JsonFormatter } from '@periodic/iridium';

const logger = createLogger({
  transports: [new ConsoleTransport({ formatter: new JsonFormatter() })],
});

await rotateRefreshToken(oldToken, {
  keyProvider,
  onTokenReused: async (jti) => {
    logger.warn('tungsten.token_reuse', { jti, severity: 'critical' });
    await revokeAllUserSessions(jti);
  },
});

// Pipe to Elasticsearch, Datadog, CloudWatch, etc.
```

### Security Monitoring

Capture authentication anomalies in your error tracker:

```typescript
app.use(async (req, res, next) => {
  try {
    req.user = await verifyAccessToken(token, { keyProvider, issuer, audience });
    next();
  } catch (err) {
    Sentry.captureException(err, { extra: { url: req.url } });
    res.status(401).json({ error: 'Unauthorized' });
  }
});
```

---

## 📝 License

MIT © [Uday Thakur](LICENSE)

---

## 🙏 Contributing

Contributions are welcome! Please read [CONTRIBUTING.md](CONTRIBUTING.md) for details on:

- Code of conduct
- Development setup
- Pull request process
- Coding standards
- Architecture principles

---

## 📞 Support

- 📧 **Email:** udaythakurwork@gmail.com
- 🐛 **Issues:** [GitHub Issues](https://github.com/udaythakur7469/periodic-tungsten/issues)
- 💬 **Discussions:** [GitHub Discussions](https://github.com/udaythakur7469/periodic-tungsten/discussions)

---

## 🌟 Show Your Support

Give a ⭐️ if this project helped you build better applications!

---

**Built with ❤️ by Uday Thakur for production-grade Node.js applications**