Tired of API tools that lock your requests in proprietary formats and GUI-only workflows?
t-req keeps standard .http files as the source of truth and lets you run them from anywhere — terminal, server, IDE, or your own code.
.http is the only request format supported by multiple independent editors — VS Code REST Client, JetBrains HTTP Client, and others. It's just raw HTTP: no DSL, no vendor syntax. Your files work without t-req.
But a file format alone doesn't get you far. t-req is the engine that makes .http files composable: hook into the request lifecycle with plugins, expose your collection as an API with treq serve, embed execution in your own code with @t-req/core, observe traffic in real time from the TUI.
One source of truth, many surfaces. The same .http file runs from the terminal, a server, a test suite, or a TypeScript script.
curl -fsSL https://t-req.io/install | bashOr as a library:
npm install @t-req/coret-req works with your existing runner (bun:test, Vitest, Jest, or node:test) because tests call client.run(...) the same way.
import { describe, expect, test } from 'vitest';
import { createClient } from '@t-req/core';
const client = createClient({
variables: { baseUrl: 'https://jsonplaceholder.typicode.com' }
});
describe('collection/users/list.http', () => {
test('returns a list of users', async () => {
const response = await client.run('./collection/users/list.http');
expect(response.status).toBe(200);
});
});# run with your existing test command
npm test
# or: pnpm test / bun test / vitest / jest / node --testUse direct CLI commands in any terminal:
treq init my-api && cd my-api
treq run requests/users/list.http # single request from CLIUse the interactive terminal app to browse files, run requests, and inspect results:
treq openInstall the t-req extension in VS Code or Cursor for syntax highlighting, inline execution, and assertion results (@t-req/plugin-assert) directly in your editor.
@t-req/core lets you execute the same .http files from scripts, test suites, and automation jobs.
This is the core idea: one request collection, many execution surfaces.
import { createClient } from '@t-req/core';
const client = createClient({
variables: { baseUrl: 'https://dummyjson.com' }
});
// 1) Login from a .http file
const loginRes = await client.run('./examples/core/e-commerce/auth/login.http', {
variables: { username: 'emilys', password: 'emilyspass' }
});
if (!loginRes.ok) throw new Error(`Login failed: ${loginRes.status}`);
const login = await loginRes.json();
client.setVariable('token', login.accessToken);
client.setVariable('userId', login.id);
// 2) Reuse variables in another .http file
const profileRes = await client.run('./examples/core/e-commerce/users/profile.http');
if (!profileRes.ok) throw new Error(`Profile lookup failed: ${profileRes.status}`);
const profile = await profileRes.json();
console.log(`${profile.firstName} <${profile.email}>`);For a larger end-to-end example, see examples/core/e-commerce/checkout-flow.ts.
Start the web app directly from your workspace:
treq webIntercept and transform at every stage of the request lifecycle.
parse.after → request.before → request.compiled → request.after → response.after
↓
error
Plugins use definePlugin and hook into any stage. Here's a retry plugin that respects Retry-After headers:
import { definePlugin } from '@t-req/core';
export default definePlugin({
name: 'retry-on-429',
version: '1.0.0',
hooks: {
async 'response.after'(input, output) {
const { response, ctx } = input;
if (response.status !== 429 || ctx.retries >= 3) return;
const retryAfter = response.headers.get('retry-after');
output.retry = {
delayMs: retryAfter ? parseInt(retryAfter) * 1000 : 1000,
reason: 'HTTP 429',
};
},
},
});Write plugins in any language using the subprocess protocol — see examples/plugins/ for Python and Ruby examples.
treq serve exposes a REST API. Call it from Python, Go, Ruby — anything that speaks HTTP.
treq serve
curl -X POST http://localhost:4097/execute \
-H "Content-Type: application/json" \
-d '{"content": "GET https://api.example.com/users\nAuthorization: Bearer {{token}}"}'templates/ship-types — Production-ready starter with Zod schemas. Type-safe API testing out of the box.
npx degit tensorix-labs/t-req/templates/ship-types my-api
cd my-api && bun install && bun testOr start from scratch:
treq init my-api && cd my-api
treq run requests/users/list.http # single request from CLIexamples/core/ — .http files and TypeScript patterns for auth, file uploads, variables, and e-commerce flows.
examples/app/ — Python, Go, and TypeScript clients for treq serve.
examples/plugins/ — Plugin examples in Python and TypeScript.
- Command resolvers —
{{$timestamp()}},{{$uuid()}}, or your own custom functions - Cookie management — automatic jar with RFC 6265 compliance
- SSE streaming —
@ssedirective for Server-Sent Events - Web dashboard — run with
treq web - TypeScript-first — full type definitions, async/await,
AsyncDisposablesupport
Open source. MIT licensed. No cloud account required.
| Package | Description |
|---|---|
| @t-req/core | HTTP parsing and execution engine |
| @t-req/app | CLI, TUI, and server |
| @t-req/web | Browser dashboard |
| @t-req/sdk | TypeScript SDK for the server |
| @t-req/plugin-base | Built-in resolvers (uuid, timestamp, base64, etc.) |
| @t-req/plugin-assert | Assertion directives for .http files |
| t-req for IDE | VS Code and Cursor compatible extension with inline execution and assertions |
See CONTRIBUTING.md for development setup and guidelines.



