@urbanisierung/pinky
v0.0.2
Published
HTTP Client TUI - Beautiful terminal-based HTTP client
Maintainers
Readme
💅 Pinky - HTTP Client TUI
A beautiful and intuitive terminal-based HTTP client built with TypeScript and Lipgloss.
✨ Features
- 🎨 Beautiful TUI - Powered by Lipgloss for a polished terminal interface with Ocean Breeze theme
- ⌨️ Keyboard Navigation - Fully navigable via keyboard shortcuts
- 📁 Request Groups - Organize your HTTP requests into collections
- 🔍 Full-Text Search - Search across all requests by name, URL, method, or group
- 🚀 Quick Execution - Execute requests and view responses instantly
- 📝 Request Details - View method, URL, headers, query params, and body
- 💾 Persistent Storage - All data saved to
~/.config/pinky - 🎯 HTTP Methods - Support for GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS
- 📊 Response Viewer - View status, headers, body, and timing information
- 🌈 Color Coding - Different colors for HTTP methods and status codes
- 📦 Demo Data - Includes sample requests for JSONPlaceholder and GitHub APIs
- 📜 Request History - Track and view recent request executions (last 100)
- 📋 Copy as cURL - One-key copy of requests as cURL commands
- 🌍 Environment Variables - Support for {{variable}} substitution in requests
🖼️ Screenshots
Groups View
╭────────────────────────────────────────────────────────────────────────────────────╮
│ 💅 Pinky HTTP Client | Groups │
│ │
│ Groups: │
│ │
│ ▶ JSONPlaceholder API (5 requests) │
│ GitHub API (2 requests) │
│ │
│ ↑/↓ Navigate Enter Select n New Group d Delete q Quit ? Help │
╰────────────────────────────────────────────────────────────────────────────────────╯Requests View
╭────────────────────────────────────────────────────────────────────────────────────╮
│ 💅 Pinky HTTP Client | Requests | JSONPlaceholder API │
│ │
│ Requests in JSONPlaceholder API: │
│ │
│ ▶ GET Get All Posts │
│ https://jsonplaceholder.typicode.com/posts │
│ POST Create Post │
│ PUT Update Post │
│ DELETE Delete Post │
│ │
│ ↑/↓ Navigate Enter Execute e Edit n New Request d Delete Esc Back q Quit │
╰────────────────────────────────────────────────────────────────────────────────────╯Response View
╭────────────────────────────────────────────────────────────────────────────────────╮
│ 💅 Pinky HTTP Client | Response │
│ │
│ Response │
│ │
│ Status: 200 OK │
│ Duration: 245ms │
│ Time: 11/10/2025, 6:00:00 PM │
│ │
│ Headers: │
│ content-type: application/json; charset=utf-8 │
│ │
│ Body: │
│ { │
│ "id": 1, │
│ "title": "Test Post" │
│ } │
│ │
│ Esc Back r Re-execute q Quit │
╰────────────────────────────────────────────────────────────────────────────────────╯🚀 Installation
Global Installation (Recommended)
Install Pinky globally using npm:
npm install -g @urbanisierung/pinkyOr using pnpm:
pnpm add -g @urbanisierung/pinkyOr using yarn:
yarn global add @urbanisierung/pinkyOnce installed, you can run Pinky from anywhere:
pinkyFrom Source
# Clone the repository
git clone https://github.com/urbanisierung/lipgloss.git
cd lipgloss/apps/pinky
# Install dependencies
pnpm install
# Build the application
pnpm build
# Run the application
pnpm start
# Or run in development mode with hot reload
pnpm dev📖 Usage
Starting Pinky
# Development mode
cd apps/pinky
pnpm dev
# Or after building
pnpm startOn first run, Pinky creates demo data with example requests to JSONPlaceholder and GitHub APIs. This data is saved to ~/.config/pinky/data.json and will persist between sessions.
Navigation
Groups View
↑/↓- Navigate between groupsEnter- Open selected groupn- Create new groupd- Delete selected group/- Search requestsq- Quit application
Requests View
↑/↓- Navigate between requestsEnter- Execute selected requeste- Edit selected requestn- Create new requestd- Delete selected requestEsc- Back to groupsq- Quit application
Editor View
Enter- Save changesEsc- Cancel editingq- Quit application
Response View
r- Re-execute requestc- Copy request as cURL commandEsc- Back to requestsq- Quit application
Search View
- Type to search across all requests
↑/↓- Navigate search resultsEnter- Select result and jump to requestBackspace- Delete search characterEsc- Cancel searchq- Quit application
History View
- View last 20 executed requests
Esc- Back to groupsq- Quit application
Environment Variables View
- View active environment and variables
Esc- Back to groupsq- Quit application
Creating and Managing Requests
Pinky currently supports viewing and executing pre-configured requests. To add or modify requests:
- Via Code: Edit the storage file at
~/.config/pinky/data.json - Via API: Use the data models in the codebase to create requests programmatically
- Interactive Editing: Coming in a future release
Example request structure:
{
"id": "unique-id",
"name": "Get Users",
"method": "GET",
"url": "https://api.example.com/users",
"headers": [
{ "key": "Accept", "value": "application/json", "enabled": true }
],
"queryParams": [
{ "key": "page", "value": "1", "enabled": true }
],
"body": "",
"bodyType": "json",
"createdAt": "2025-01-01T00:00:00.000Z",
"updatedAt": "2025-01-01T00:00:00.000Z"
}Executing a Request
- Navigate to a group and press
Enterto open it - Use
↑/↓to select a request - Press
Enterto execute the request - View the response with status, headers, and body
- Press
rto re-execute orEscto go back - Press
cto copy the request as a cURL command
Searching for Requests
- From the groups view, press
/to open search - Type your search query (searches name, URL, method, and group)
- Use
↑/↓to navigate results - Press
Enterto select a result and jump to that request - Press
Escto cancel search
Viewing Request History
- From the groups view, press
hto open history - View recent request executions with status codes and timing
- History shows the last 20 requests (stores up to 100)
- Press
Escto go back
Using Environment Variables
Environment variables allow you to use dynamic values in your requests using the {{variable}} syntax.
Setting up environments:
- Create an environments file at
~/.config/pinky/environments.json:
{
"environments": [
{
"id": "env-1",
"name": "Development",
"variables": [
{ "key": "API_URL", "value": "http://localhost:3000", "enabled": true },
{ "key": "API_KEY", "value": "dev-key-123", "enabled": true }
]
},
{
"id": "env-2",
"name": "Production",
"variables": [
{ "key": "API_URL", "value": "https://api.example.com", "enabled": true },
{ "key": "API_KEY", "value": "prod-key-456", "enabled": true }
]
}
],
"currentEnvironmentId": "env-1",
"version": "0.2.0"
}- Use variables in your requests:
{
"url": "{{API_URL}}/users",
"headers": [
{ "key": "Authorization", "value": "Bearer {{API_KEY}}", "enabled": true }
]
}- Press
vfrom groups view to see active environment and variables - Variables are automatically substituted when requests are executed
- Variables work in URLs, headers, query parameters, and body
Copying Requests as cURL
- Execute a request
- From the response view, press
c - The cURL command is copied to your clipboard (if available)
- If clipboard copy fails, the command is shown in a message
- Environment variables are automatically substituted in the cURL command
Request Configuration
Each request can be configured with:
- Name - Descriptive name for the request
- Method - HTTP method (GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS)
- URL - Target URL
- Headers - Custom HTTP headers (can be enabled/disabled individually)
- Query Parameters - URL query parameters (can be enabled/disabled individually)
- Body - Request body (for POST, PUT, PATCH)
- Body Type - Text or JSON
Common Use Cases
API Testing
1. Create a group for your API
2. Add requests for each endpoint
3. Configure headers (auth tokens, content-type)
4. Execute and verify responsesQuick HTTP Checks
1. Use demo data as templates
2. Execute GET requests to check API health
3. View response times and status codesDevelopment Workflow
1. Group requests by feature or service
2. Toggle headers/params for different environments
3. Re-execute requests quickly during developmentStorage
All data is automatically saved to ~/.config/pinky/:
- data.json - Groups and requests
- history.json - Request execution history (last 100 entries)
- environments.json - Environment variables and active environment
Data is saved automatically after each change.
🎨 UI Overview
Pinky uses a beautiful TUI layout with:
- Header - Application title and current view
- Content Area - Main content (groups, requests, editor, response)
- Footer - Keyboard shortcuts for current view
Color Coding
- GET - Green
- POST - Yellow
- PUT - Orange
- PATCH - Purple
- DELETE - Red
- HEAD - Cyan
- OPTIONS - Gray
Response Status Colors
- 2xx Success - Green
- 3xx Redirect - Blue
- 4xx Client Error - Red
- 5xx Server Error - Red
- Error - Red
🛠️ Development
Tech Stack
- TypeScript - Type-safe JavaScript (ES2022)
- Node.js - Runtime (v18+)
- @urbanisierung/lipgloss - Terminal UI framework with TUI shell
- Vitest - Fast unit test framework
- Biome - Lightning-fast linting and formatting
Architecture
Pinky follows a clean architecture pattern:
- UI Layer (
ui.ts) - Renders TUI using Lipgloss shell - Application Layer (
index.ts) - Main app logic and keyboard handling - Service Layer (
http-client.ts,storage.ts) - Business logic - Domain Layer (
types.ts) - Core data models - Utilities (
utils.ts,demo.ts) - Helper functions
Project Structure
src/
├── index.ts # Main application entry point
├── types.ts # TypeScript type definitions
├── storage.ts # Data persistence service
├── http-client.ts # HTTP request execution
├── ui.ts # UI rendering with Lipgloss
├── utils.ts # Helper utilities
├── demo.ts # Demo data generator
└── demo-screenshots.ts # Screenshot generator for docs
test/
├── storage.test.ts # Storage tests
├── http-client.test.ts # HTTP client tests
└── utils.test.ts # Utility function testsRunning Tests
# Run all tests
pnpm test
# Run tests in watch mode
pnpm test:watch
# Run with coverage (coming soon)
pnpm test:coverageCurrent test coverage:
- ✅ 19 tests passing
- ✅ Storage service tests
- ✅ HTTP client tests
- ✅ Utility function tests
Linting
pnpm lint📝 Examples
Example Request
{
"name": "Get Users",
"method": "GET",
"url": "https://jsonplaceholder.typicode.com/users",
"headers": [
{ "key": "Accept", "value": "application/json", "enabled": true }
],
"queryParams": [],
"body": "",
"bodyType": "json"
}Example Group
{
"name": "JSONPlaceholder API",
"requests": [
{ "name": "Get Users", "method": "GET", "url": "https://jsonplaceholder.typicode.com/users" },
{ "name": "Get Posts", "method": "GET", "url": "https://jsonplaceholder.typicode.com/posts" },
{ "name": "Create Post", "method": "POST", "url": "https://jsonplaceholder.typicode.com/posts" }
]
}🔮 Roadmap
v0.2.0 (Planned)
- ✅ Interactive request editing in TUI
- ✅ Full-text search across all requests
- ✅ Request history and recent requests
- ✅ Copy request as cURL command
- ✅ Environment variables support
v0.3.0 (Planned)
- [ ] Import/Export collections (JSON, Postman)
- [ ] Authentication helpers (Basic, Bearer, OAuth)
- [ ] Request chaining and variables
- [ ] Response caching
- [ ] Custom color themes
v1.0.0 (Planned)
- [ ] GraphQL support
- [ ] WebSocket support
- [ ] Request scripts (pre-request, post-request)
- [ ] Team collaboration features
- [ ] Syntax highlighting for JSON/XML
Known Limitations
- Request editing is view-only in the TUI; use the JSON file to modify request details
- Environment switching requires editing the environments.json file manually
- No import/export of collections yet
- History view is read-only (no ability to re-execute from history yet)
🐛 Troubleshooting
App won't start
- Ensure Node.js v18+ is installed
- Run
pnpm installto install dependencies - Check terminal size (minimum 60x20 recommended)
Data not saving
- Ensure write permissions to
~/.config/pinky - Check disk space availability
Requests failing
- Verify URL is correct and accessible
- Check network connectivity
- Review request headers and body
UI looks broken
- Ensure terminal supports ANSI colors
- Try resizing terminal window
- Use a modern terminal emulator (iTerm2, Windows Terminal, etc.)
🤝 Contributing
Contributions are welcome! Please read the CONTRIBUTING.md in the root repository.
📄 License
MIT - See LICENSE in the root repository.
🙏 Acknowledgments
Made with 💅 by the Lipgloss team
