npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@harshvz/lingodev-cli

v1.0.0

Published

CLI-based translation pipeline using lingo.dev SDK

Downloads

11

Readme

Lingo CLI - Translation Pipeline

A production-grade CLI tool for translating files using the lingo.dev JavaScript SDK.

🚀 Features

  • Smart Path Handling: Translate single files, directories, or use . for current directory
  • Format Preservation: Maintains formatting for Markdown, JSON, and text files
  • Recursive Scanning: Automatically finds all supported files in directories
  • Auto-detection: Source language can be auto-detected
  • Safe Writing: Never overwrites existing files
  • Comprehensive Reporting: Detailed progress and error reporting
  • Clean Architecture: Service-based design for maintainability

📦 Installation

From Source

# Clone or navigate to the project
cd LingoDev

# Install dependencies
npm install

# Build the project
npm run build

# Link globally (optional)
npm link

From npm (when published)

npm install -g lingo-cli

⚙️ Configuration

There are two ways to configure your API key:

1. Using CLI (Recommended)

You can save your API key globally using the CLI:

translate --set-key your_api_key_here

To remove the saved key:

translate --reset-key

2. Using Environment Variables

Create a .env file in the directory where you run the command:

LINGODOTDEV_API_KEY=your_api_key_here

Or set it in your terminal session:

export LINGODOTDEV_API_KEY=your_api_key_here

🌍 Supported Languages

To see a list of all supported languages, run:

translate --languages
# or
translate -l

This will display all available language codes (e.g., en, hi, fr, ja) and their full names.

📖 Usage

Command Syntax

translate <path> [sourceLanguage] [targetLanguage]

Arguments

| Argument | Description | Default | Required | | ---------------- | ------------------------------------------------------ | ------- | -------- | | path | File or directory path (use . for current directory) | - | ✓ | | sourceLanguage | Source language code or auto | auto | ✗ | | targetLanguage | Target language code | en | ✗ |

Flags

| Flag | Description | | ------------------- | ------------------------------------ | | --languages, -l | Show all supported language codes | | --set-key | Save API key to global configuration | | --reset-key | Remove saved API key | | --help, -h | Show help message | | --version, -v | Show version information |

Examples

# Translate all files in current directory to English (auto-detect source)
translate .

# Translate to Hindi (auto-detect source)
translate . auto hi

# Translate from Hindi to English
translate . hi en

# Translate a specific directory from French to English
translate ./docs fr en

# Translate a single file from Spanish to English
translate ./readme.md es en

Supported File Types

| Extension | Description | Translation Behavior | | --------- | ----------- | -------------------------------------------------- | | .md | Markdown | Preserves formatting, code blocks remain unchanged | | .json | JSON | Translates values only, keys remain unchanged | | .txt | Plain text | Translates entire content |

Output Files

Translated files are saved with a language suffix:

file.md       → file.en.md
data.json     → data.en.json
readme.txt    → readme.hi.txt

🏗️ Architecture

The project follows a clean, service-based architecture:

src/
├── bin/
│   └── translate.ts          # CLI entry point
├── services/
│   ├── CLIService.ts          # Argument parsing & validation
│   ├── ConfigService.ts       # Configuration management
│   ├── FileScannerService.ts  # File system scanning
│   ├── TranslationService.ts  # Translation logic
│   └── FileWriterService.ts   # File writing
├── App.ts                     # Main orchestrator
└── index.ts                   # Package exports

Service Responsibilities

1️⃣ CLIService

  • Parses command-line arguments
  • Validates paths and language codes
  • Resolves . to process.cwd()
  • Provides usage help

2️⃣ ConfigService

  • Singleton pattern for configuration
  • Reads environment variables
  • Provides default settings
  • Validates API configuration

3️⃣ FileScannerService

  • Recursively scans directories
  • Filters by supported file types
  • Returns absolute file paths

4️⃣ TranslationService

  • Wraps lingo.dev SDK
  • Format-aware translation:
    • Markdown: Preserves code blocks and formatting
    • JSON: Translates values, keeps keys intact
    • Text: Translates entire content

5️⃣ FileWriterService

  • Generates localized filenames
  • Safely writes files
  • Prevents overwriting existing files

🎯 How It Works: translate . hi en

Let's trace through what happens when you run translate . hi en:

1. CLI Parsing (CLIService)

// Input: ['node', 'translate.js', '.', 'hi', 'en']
{
  path: '/absolute/path/to/current/directory',  // '.' resolved to process.cwd()
  sourceLanguage: 'hi',
  targetLanguage: 'en'
}

2. File Scanning (FileScannerService)

// Recursively scans directory
[
  "/absolute/path/readme.md",
  "/absolute/path/data.json",
  "/absolute/path/docs/guide.md",
];
// Only .md, .json, .txt files included

3. Translation (TranslationService)

For each file:

// Read content
const content = await readFile(filePath);

// Translate based on file type
if (fileType === ".md") {
  // Preserve markdown formatting, protect code blocks
  translated = await translateMarkdown(content, "hi", "en");
} else if (fileType === ".json") {
  // Translate values only, keep keys
  translated = await translateJson(content, "hi", "en");
} else {
  // Translate entire content
  translated = await translateText(content, "hi", "en");
}

4. File Writing (FileWriterService)

// Generate output filename
'readme.md' → 'readme.en.md'
'data.json' → 'data.en.json'

// Write to same directory
await writeFile(outputPath, translatedContent);

5. Summary Report

═══════════════════════════════════════════════════════════
📊 Translation Summary
═══════════════════════════════════════════════════════════
✔  8 file(s) translated
⚠  3 file(s) skipped
❌ 1 file(s) failed
═══════════════════════════════════════════════════════════

🔧 Development

Build

npm run build

Watch Mode

npm run dev

Run Locally

# After building
npm run translate -- . hi en

# Or use node directly
node dist/bin/translate.js . hi en

🧪 Error Handling

The CLI handles various error scenarios:

  • Invalid paths: Clear error message with path validation
  • Empty directories: Warns when no supported files found
  • Unsupported file types: Silently skips with summary
  • SDK failures: Catches and reports translation errors
  • File conflicts: Skips existing files to prevent overwrites
  • Missing API key: Validates configuration before processing

📝 Example Output

🚀 Starting translation pipeline...

📁 Path: /Users/harsh/projects/docs
🌍 Translation: hi → en

🔍 Scanning for files...
✓ Found 5 file(s) to translate

📄 Processing: /Users/harsh/projects/docs/readme.md
📡 Translating: hi → en
   ✓ Saved to: /Users/harsh/projects/docs/readme.en.md

📄 Processing: /Users/harsh/projects/docs/data.json
📡 Translating: hi → en
   ✓ Saved to: /Users/harsh/projects/docs/data.en.json

═══════════════════════════════════════════════════════════
📊 Translation Summary
═══════════════════════════════════════════════════════════
✔  5 file(s) translated
⚠  0 file(s) skipped
❌ 0 file(s) failed
═══════════════════════════════════════════════════════════

🔌 Integrating lingo.dev SDK

The current implementation includes a placeholder for the lingo.dev SDK. To integrate the actual SDK:

  1. Install the SDK:
npm install @lingo.dev/sdk
  1. Update TranslationService.ts:
import { LingoClient } from '@lingo.dev/sdk';

private async callLingoApi(
  text: string,
  sourceLanguage: string,
  targetLanguage: string
): Promise<string> {
  const client = new LingoClient({
    apiKey: this.config.getApiKey()
  });

  const result = await client.translate({
    text,
    from: sourceLanguage,
    to: targetLanguage
  });

  return result.translatedText;
}

📄 License

MIT

🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.


Built with ❤️ using TypeScript and lingo.dev