@pings/phtps
v1.0.1
Published
A modern HTTP client built on native fetch — with plugins for retry, auth, cache, queue, encryption, streaming (SSE/NDJSON), pagination, and payment security.
Maintainers
Readme
Phtps
A modern HTTP client built on native fetch.
Plugins for retry, auth, cache, deduplication, queue, encryption, streaming (SSE + NDJSON), pagination, and payment security. Zero dependencies. Full TypeScript.
npm install phtpsWhy Phtps
Most HTTP clients give you a thin wrapper around fetch and leave the hard parts to you. Phtps ships the features that production apps actually need — without pulling in extra dependencies.
| Feature | Phtps | Axios | Ky | Got | |---|---|---|---|---| | Retry with backoff | ✅ built-in | ❌ plugin needed | ⚠️ basic | ✅ | | Token refresh (401 queue) | ✅ | ❌ manual | ❌ manual | ❌ manual | | Proactive token rotation | ✅ | ❌ | ❌ | ❌ | | Request deduplication | ✅ | ❌ | ❌ | ❌ | | Response cache + adapters | ✅ | ❌ | ❌ | ❌ | | Concurrency queue | ✅ | ❌ | ❌ | ❌ | | SSE streaming | ✅ | ❌ | ❌ | ❌ | | NDJSON streaming | ✅ | ❌ | ❌ | ❌ | | Payload encryption (AES-GCM) | ✅ | ❌ | ❌ | ❌ | | Payment security (HMAC) | ✅ | ❌ | ❌ | ❌ | | CSRF protection | ✅ full | ⚠️ basic | ❌ | ❌ | | Pagination (all strategies) | ✅ | ❌ | ❌ | ❌ | | Plugin system | ✅ typed | ❌ | ⚠️ hooks | ❌ | | Zero dependencies | ✅ | ❌ | ✅ | ❌ | | Full TypeScript | ✅ | ✅ | ✅ | ✅ |
Quick Start
import { Phtps } from 'phtps';
const { data } = await Phtps.get('/api/users');
const { data } = await Phtps.post('/api/users', { name: 'Alice' });Custom Instance
import { createHttpClient } from 'phtps';
import { RetryPlugin, AuthPlugin, CachePlugin } from 'phtps/plugins';
const api = createHttpClient({
baseURL: 'https://api.example.com',
timeout: 10000,
});
api.use([
RetryPlugin(),
AuthPlugin(),
CachePlugin(),
]);
export default api;Plugins
Install only what you need. Every plugin is tree-shakeable.
import {
RetryPlugin,
AuthPlugin,
CachePlugin,
DedupePlugin,
QueuePlugin,
EncryptionPlugin,
CsrfPlugin,
PaginationPlugin,
PaymentPlugin,
} from 'phtps/plugins';RetryPlugin
api.use(RetryPlugin());
await api.get('/api/data', {
retries: 3,
retryDelay: 1000, // exponential: 1s, 2s, 4s ± jitter
});AuthPlugin — token refresh on 401
api.use(AuthPlugin());
await api.get('/api/me', {
onTokenRefresh: async () => {
const { token } = await refreshToken();
return token;
},
});CachePlugin
api.use(CachePlugin());
await api.get('/api/users', { useCache: true, cacheTTL: 60000 });SSE Streaming
const stream = await api.stream('/api/chat', {
method: 'POST',
body: { messages },
streamType: 'sse',
});
const reader = stream.data.getReader();
while (true) {
const { done, value } = await reader.read();
if (done) break;
console.log(value.data); // parsed per-event
}
stream.cancel();PaginationPlugin — fetch all pages
api.use(PaginationPlugin());
const { data } = await api.get('/api/posts', {
paginate: { strategy: 'cursor', cursorField: 'nextCursor', limit: 200 },
});
// data is all items merged across all pagesPaymentPlugin — HMAC signing + idempotency
api.use(PaymentPlugin({
secretKey: getRuntimeKey(),
signRequests: true,
idempotency: true,
maskSensitiveData: true,
}));Error Handling
try {
await api.get('/api/users');
} catch (err) {
if (err.isTimeout) { /* timed out */ }
if (err.isCancel) { /* aborted */ }
if (err.response) {
console.log(err.response.status);
console.log(err.response.data);
}
}TypeScript
import type { HttpClientConfig, HttpResponse, HttpError, PhtpsPlugin } from 'phtps';
const { data } = await api.get<User[]>('/api/users');
// ^ User[]Requirements
- Browser: Any modern browser (Chrome 89+, Firefox 90+, Safari 15+)
- Node.js: 18.0.0 or later
- Dependencies: None
Documentation
Full documentation: https://phtps.dev/docs
Contributing
See CONTRIBUTING.md.
License
MIT © 2026 Phtps Contributors
