{"id":21268788,"url":"https://github.com/reliverse/relinka","last_synced_at":"2025-07-11T05:30:29.580Z","repository":{"id":261479499,"uuid":"882878261","full_name":"reliverse/relinka","owner":"reliverse","description":"⌨️ @reliverse/prompts: A modern, type-safe, crash-resistant library for creating seamless, typesafe prompts in CLI applications. Designed for simplicity and elegance, it enables intuitive and robust user interactions.","archived":false,"fork":false,"pushed_at":"2024-11-19T02:25:08.000Z","size":12249,"stargazers_count":2,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2024-11-19T03:24:10.043Z","etag":null,"topics":["blefnk","javascript","js-lib","js-library","library","npm-package","prompts","reliverse"],"latest_commit_sha":null,"homepage":"https://reliverse.org","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/reliverse.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-11-04T00:57:36.000Z","updated_at":"2024-11-19T02:20:03.000Z","dependencies_parsed_at":"2024-11-06T19:44:12.303Z","dependency_job_id":"19fbab75-64fc-43e6-ac04-264a41c64068","html_url":"https://github.com/reliverse/relinka","commit_stats":null,"previous_names":["reliverse/prompts","reliverse/relinka"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reliverse%2Frelinka","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reliverse%2Frelinka/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reliverse%2Frelinka/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reliverse%2Frelinka/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/reliverse","download_url":"https://codeload.github.com/reliverse/relinka/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225622929,"owners_count":17498168,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["blefnk","javascript","js-lib","js-library","library","npm-package","prompts","reliverse"],"created_at":"2024-11-21T08:06:22.771Z","updated_at":"2025-07-11T05:30:29.572Z","avatar_url":"https://github.com/reliverse.png","language":"TypeScript","funding_links":["https://github.com/sponsors/blefnk"],"categories":["TypeScript"],"sub_categories":[],"readme":"# Relinka: Logging that Actually Feels Good\r\n\r\n[sponsor](https://github.com/sponsors/blefnk) — [discord](https://discord.gg/Pb8uKbwpsJ) — [repo](https://github.com/reliverse/relinka) — [npm](https://npmjs.com/@reliverse/relinka)\r\n\r\n\u003e **@reliverse/relinka** is a modern logging library that actually *feels* right. It's not just pretty output — it's a system: smart formatting, file-safe logging, runtime config support, and a `fatal` mode built for developers who care about correctness. Whether you're building CLI tools, SDKs, or full-stack apps — Relinka helps you log with intention.\r\n\r\n## Why Relinka\r\n\r\n- 🧙 **Drop-in replacement** for `node:console`, `consola`, or your internal logger\r\n- 💬 **12 log levels**: `info`, `warn`, `success`, `error`, `verbose`, `fatal`, `log`, `step`, `box`, `message`, `internal`, `null`\r\n- 🎨 **Beautiful terminal output** with automatic color handling and Unicode support\r\n- 📁 **Smart file logging** with buffering, rotation, cleanup, and date-based naming\r\n- 🧠 **Structured formatting** for objects, errors, and stack traces\r\n- ⚙️ **Runtime configuration** via `.config/relinka.ts` or `relinka.config.ts`\r\n- 🚨 **Fatal logging** that halts execution and triggers debugger in development\r\n- 🧩 **Dual syntax support** - both function calls (`relinka(\"info\", \"Hello world\")`) and method chaining (`relinka.info(\"Hello world\")`)\r\n- ⚡ **Performance optimized** with intelligent buffering and async support\r\n- 🛎️ **Dler-ready** - if you use `dler build`, all `internal`-level logs will be removed from the built dist\r\n\r\n## Quick Start\r\n\r\n### 1. Install\r\n\r\n```bash\r\nbun add @reliverse/relinka\r\n```\r\n\r\n### 2. Basic Usage\r\n\r\n```ts\r\nimport { relinka, relinkaConfig, relinkaShutdown } from \"@reliverse/relinka\";\r\n\r\nasync function main() {\r\n  // Load configuration (required at start)\r\n  await relinkaConfig();\r\n  \r\n  // Log with different levels\r\n  relinka(\"info\", \"Application started\");\r\n  relinka(\"success\", \"Configuration loaded successfully\");\r\n  relinka(\"warn\", \"This is a warning\");\r\n  relinka(\"error\", \"Something went wrong\");\r\n  \r\n  // Use method syntax (also supported)\r\n  relinka.info(\"Another info message\");\r\n  relinka.success(\"Another success message\");\r\n  \r\n  // Clean shutdown (required at end)\r\n  await relinkaShutdown();\r\n}\r\n\r\nmain();\r\n```\r\n\r\n## Log Levels\r\n\r\nRelinka supports 12 different log levels, each with customizable symbols and colors:\r\n\r\n| Level | Symbol | Description |\r\n|-------|--------|-------------|\r\n| `info` | ◈ | General information |\r\n| `success` | ✓ | Success messages |\r\n| `warn` | ⚠ | Warnings |\r\n| `error` | ✖ | Non-fatal errors |\r\n| `fatal` | ‼ | Fatal errors + error throwing |\r\n| `verbose` | ✱ | Debug information |\r\n| `log` | │ | General logging |\r\n| `step` | → | Progress steps |\r\n| `box` | ■ | Boxed messages |\r\n| `message` | 🞠 | General messages |\r\n| `internal` | ⚙ | Internal system logs |\r\n| `null` | (none) | No symbol or spacing |\r\n\r\n## API Reference\r\n\r\n### Core Functions\r\n\r\n#### `relinka(level, message, ...args)`\r\n\r\nMain logging function with dual syntax support.\r\n\r\n```ts\r\n// Function syntax\r\nrelinka(\"info\", \"Hello world\");\r\nrelinka(\"error\", \"Something broke\", { error: \"details\" });\r\n\r\n// Method syntax\r\nrelinka.info(\"Hello world\");\r\nrelinka.error(\"Something broke\", { error: \"details\" });\r\n```\r\n\r\n#### `relinkaAsync(level, message, ...args)`\r\n\r\nAsync version that waits for configuration to load.\r\n\r\n```ts\r\nawait relinkaAsync(\"info\", \"Async message\");\r\nawait relinkaAsync(\"success\", \"Operation completed\");\r\n```\r\n\r\n#### `relinkaConfig(options?)`\r\n\r\nLoad configuration with optional fresh log file support.\r\n\r\n```ts\r\n// Basic config loading\r\nawait relinkaConfig();\r\n\r\n// With fresh log file (clears existing log file)\r\nawait relinkaConfig({ supportFreshLogFile: true });\r\n```\r\n\r\n#### `relinkaShutdown()`\r\n\r\nFlush all buffers and clean up resources. **Always call this at the end of your program.**\r\n\r\n```ts\r\nawait relinkaShutdown();\r\n```\r\n\r\n### Utility Functions\r\n\r\n#### `log`, `logger`\r\n\r\nAliases for the main `relinka` function.\r\n\r\n```ts\r\nimport { log, logger } from \"@reliverse/relinka\";\r\n\r\nlog(\"info\", \"Using alias\");\r\nlogger.success(\"Another alias\");\r\n```\r\n\r\n#### `message(msg, ...args)`\r\n\r\nConvenience function for general messages.\r\n\r\n```ts\r\nimport { message } from \"@reliverse/relinka\";\r\nmessage(\"This is a general message\");\r\n```\r\n\r\n#### `step(msg, ...args)`\r\n\r\nConvenience function for progress steps.\r\n\r\n```ts\r\nimport { step } from \"@reliverse/relinka\";\r\nstep(\"Step 1: Initialize\");\r\nstep(\"Step 2: Load config\");\r\n```\r\n\r\n## Configuration\r\n\r\nCreate a configuration file to customize Relinka's behavior:\r\n\r\n### File Locations (in order of priority)\r\n\r\n1. `relinka.config.ts` (project root) - **highest priority**\r\n2. `.config/relinka.ts` - **lower priority**\r\n\r\n### Configuration Example\r\n\r\n```ts\r\nimport { defineConfig } from \"@reliverse/relinka\";\r\n\r\nexport default defineConfig({\r\n  // Enable verbose logging\r\n  verbose: false,\r\n\r\n  // Timestamp configuration\r\n  timestamp: {\r\n    enabled: true,\r\n    format: \"YYYY-MM-DD HH:mm:ss.SSS\",\r\n  },\r\n\r\n  // File logging\r\n  saveLogsToFile: true,\r\n  logFile: {\r\n    outputPath: \"logs/app.log\",\r\n    nameWithDate: \"append-before\", // \"disable\" | \"append-before\" | \"append-after\"\r\n    freshLogFile: true, // Clear log file on each run\r\n  },\r\n\r\n  // Log rotation\r\n  dirs: {\r\n    maxLogFiles: 10, // Keep only the 10 most recent log files\r\n  },\r\n\r\n  // Performance tuning\r\n  bufferSize: 4096, // 4KB buffer before flushing\r\n  maxBufferAge: 5000, // 5 seconds max buffer age\r\n  cleanupInterval: 10000, // 10 seconds between cleanups\r\n\r\n  // Customize log levels\r\n  levels: {\r\n    success: {\r\n      symbol: \"✓\",\r\n      fallbackSymbol: \"[OK]\",\r\n      color: \"greenBright\",\r\n      spacing: 3,\r\n    },\r\n    info: {\r\n      symbol: \"◈\",\r\n      fallbackSymbol: \"[i]\",\r\n      color: \"cyanBright\",\r\n      spacing: 3,\r\n    },\r\n    // ... customize other levels\r\n  },\r\n});\r\n```\r\n\r\n### Configuration Options\r\n\r\n| Option | Type | Default | Description |\r\n|--------|------|---------|-------------|\r\n| `verbose` | `boolean` | `false` | Enable verbose logging |\r\n| `saveLogsToFile` | `boolean` | `false` | Save logs to file |\r\n| `disableColors` | `boolean` | `false` | Disable color output |\r\n| `timestamp.enabled` | `boolean` | `false` | Add timestamps to logs |\r\n| `timestamp.format` | `string` | `\"YYYY-MM-DD HH:mm:ss.SSS\"` | Timestamp format |\r\n| `logFile.outputPath` | `string` | `\"logs.log\"` | Log file path |\r\n| `logFile.nameWithDate` | `string` | `\"disable\"` | Date handling in filename |\r\n| `logFile.freshLogFile` | `boolean` | `true` | Clear log file on startup |\r\n| `dirs.maxLogFiles` | `number` | `0` | Maximum log files to keep |\r\n| `bufferSize` | `number` | `4096` | Buffer size in bytes |\r\n| `maxBufferAge` | `number` | `5000` | Max buffer age in ms |\r\n| `cleanupInterval` | `number` | `10000` | Cleanup interval in ms |\r\n\r\n## File Logging\r\n\r\n### File Naming Patterns\r\n\r\n- **Default**: `logs.log`\r\n- **With subdirectory**: `logs/app.log`\r\n- **With date prefix**: `2025-01-15-logs.log`\r\n- **With date suffix**: `logs-2025-01-15.log`\r\n- **Combined**: `logs/2025-01-15-app.log`\r\n\r\n### Automatic Cleanup\r\n\r\nWhen `maxLogFiles` is set, Relinka automatically:\r\n\r\n- Keeps only the N most recent log files\r\n- Deletes older files during cleanup\r\n- Runs cleanup periodically and on shutdown\r\n\r\n## Advanced Usage\r\n\r\n### Fatal Logging\r\n\r\nFatal logs throw errors and halt execution:\r\n\r\n```ts\r\n// This will throw an error and trigger debugger in development\r\nrelinka(\"fatal\", \"Critical system failure\");\r\n// or\r\nrelinka.fatal(\"Critical system failure\");\r\n```\r\n\r\n### Box Formatting\r\n\r\nCreate visually appealing boxed messages:\r\n\r\n```ts\r\nrelinka(\"box\", \"This message will be displayed in a box\");\r\nrelinka.box(\"This also works with method syntax\");\r\n```\r\n\r\n### Async Context\r\n\r\nUse `relinkaAsync` when you need to ensure configuration is loaded:\r\n\r\n```ts\r\nawait relinkaAsync(\"info\", \"This waits for config to load\");\r\n```\r\n\r\n### Clear Terminal\r\n\r\nClear the terminal output:\r\n\r\n```ts\r\nrelinka(\"clear\", \"\");\r\n// or\r\nrelinka.clear();\r\n```\r\n\r\n### Empty Lines\r\n\r\nAdd blank lines to output:\r\n\r\n```ts\r\nrelinka(\"info\", \"\");\r\n```\r\n\r\n## Best Practices\r\n\r\n### 1. Always Initialize and Shutdown\r\n\r\n```ts\r\nasync function main() {\r\n  await relinkaConfig(); // At the start\r\n  \r\n  // Your application logic\r\n  relinka(\"info\", \"App running\");\r\n  \r\n  await relinkaShutdown(); // At the end\r\n}\r\n```\r\n\r\n### 2. Use Appropriate Log Levels\r\n\r\n```ts\r\nrelinka(\"info\", \"User logged in\"); // General info\r\nrelinka(\"success\", \"Payment processed\"); // Success events\r\nrelinka(\"warn\", \"High memory usage\"); // Warnings\r\nrelinka(\"error\", \"Database connection failed\"); // Recoverable errors\r\nrelinka(\"fatal\", \"Critical system failure\"); // Unrecoverable errors\r\n```\r\n\r\n### 3. Leverage Verbose Logging\r\n\r\n```ts\r\nrelinka(\"verbose\", \"Debug information\"); // Only shown when verbose=true\r\n```\r\n\r\n### 4. Structure Complex Data\r\n\r\n```ts\r\nrelinka(\"error\", \"API request failed\", {\r\n  endpoint: \"/api/users\",\r\n  statusCode: 500,\r\n  error: error.message\r\n});\r\n```\r\n\r\n## Performance Features\r\n\r\n- **Intelligent Buffering**: Logs are buffered and flushed efficiently\r\n- **Async File Operations**: Non-blocking file writes\r\n- **Memory Management**: Automatic cleanup of old log files\r\n- **Unicode Detection**: Automatic fallback for non-Unicode terminals\r\n\r\n## FAQ\r\n\r\n### Why does my terminal hang after logging?\r\n\r\n→ You forgot to call `await relinkaShutdown()` at the end of your program. This is required to flush buffers.\r\n\r\n### Why isn't my configuration loading?\r\n\r\n→ Make sure you call `await relinkaConfig()` at the start of your application.\r\n\r\n### Does `fatal` always throw?\r\n\r\n→ Yes, `fatal` logs always throw errors and halt execution. In development mode, they also trigger the debugger.\r\n\r\n### How do I disable colors?\r\n\r\n→ Set `disableColors: true` in your configuration or use `NO_COLOR=1` environment variable.\r\n\r\n### Can I use Relinka in both sync and async contexts?\r\n\r\n→ Yes! Use `relinka()` for sync operations and `relinkaAsync()` when you need to use some advanced features (like typing text streaming animation).\r\n\r\n### What's the difference between `log` and `message` levels?\r\n\r\n→ `log` uses a pipe symbol (│) and is for general logging, while `message` uses a different symbol (🞠) and is for general messages.\r\n\r\n## Ecosystem\r\n\r\nRelinka works great with other Reliverse tools:\r\n\r\n- **CLI Development**: [`@reliverse/prompts`](https://npmjs.com/@reliverse/prompts)\r\n- **Bundling**: [`@reliverse/dler`](https://npmjs.com/@reliverse/dler)\r\n\r\n## Roadmap\r\n\r\n- [x] File logging with rotation\r\n- [x] Timestamp support\r\n- [x] Date-based file naming\r\n- [x] Automatic cleanup\r\n- [x] Fatal logging with debugger\r\n- [x] Runtime configuration\r\n- [x] Dual syntax support\r\n- [ ] Plugin system\r\n- [ ] Custom formatters\r\n- [ ] CLI interface for log management\r\n- [ ] WebSocket streaming\r\n- [ ] Structured logging (JSON)\r\n\r\n## Contributing\r\n\r\nWe welcome contributions! Please see our [contributing guide](CONTRIBUTING.md) for details.\r\n\r\n## License\r\n\r\n💖 MIT © 2025 [blefnk Nazar Kornienko](https://github.com/blefnk)\r\n\r\n## Acknowledgments\r\n\r\nRelinka is inspired by these excellent logging libraries:\r\n\r\n- [unjs/consola](https://github.com/unjs/consola) - Console logging for Node.js\r\n- [winston](https://github.com/winstonjs/winston) - Multi-transport logging\r\n- [pino](https://github.com/pinojs/pino) - Fast Node.js logger\r\n- [node-bunyan](https://github.com/trentm/node-bunyan) - JSON logging\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freliverse%2Frelinka","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Freliverse%2Frelinka","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freliverse%2Frelinka/lists"}