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

@hkonda/loco-translate

v1.1.11

Published

Self-hosted translation manager — auto-discovers text, AI translations, Svelte dashboard, CDN client.

Readme

Loco

Open-source translation engine for any website or app. Drop in a single <script> tag, manage translations from a dashboard, and let AI handle the heavy lifting.

Two integration modes: Server Mode (live API-driven) and File Mode (static JSON, zero server dependency).


Quick Start — NPM Package

The fastest way to run Loco. No cloning required.

1. Install and Start

npm install -g @hkonda/loco-translate
loco

Or without a global install:

npx @hkonda/loco-translate

On first run, the terminal prints your dashboard URL, CDN snippet, and API key:

  🌐 Loco Translation Manager

  Dashboard : http://<your-ip>:6101/dashboard/
  CDN script: http://<your-ip>:6101/cdn/loco.js
  API key   : <auto-generated>

  Paste into any page:

  <script src="http://<your-ip>:6101/cdn/loco.js"></script>
  <script>Loco.init({ apiUrl: 'http://<your-ip>:6101', apiKey: '<your-key>' });</script>

2. Open the Dashboard

Navigate to the Dashboard URL printed above (e.g. http://localhost:6101/dashboard/).

3. Add the Snippet to Your Page

Copy the <script> tags from the terminal output and paste them into any HTML page. When that page loads, Loco auto-discovers all text and sends it to the dashboard as Pending items.

4. Translate

  1. In the dashboard, approve phrases in the Pending tab
  2. Use AI Translate (requires a BlueHive API key) or edit translations manually
  3. Call Loco.apply('fr') in the browser console to preview translations live

Configuration

Run loco --help to see all options:

Options:
  -p, --port <number>      Port to listen on (default: 6101)
  -d, --data-dir <path>    Directory for loco.db (default: .loco/ in cwd)
  -h, --help               Show this help message

Or set environment variables (in a .env file or your shell):

| Variable | Flag equivalent | Default | Description | |---|---|---|---| | PORT | -p, --port | 6101 | Server port | | LOCO_DATA_DIR | -d, --data-dir | .loco/ in cwd | Directory where loco.db is stored | | BASE_PATH | — | (empty) | URL prefix for reverse-proxy deployments | | BLUEHIVE_API_KEY | — | (none) | BlueHive key for AI translations | | PUBLIC_URL | — | (auto) | Override the printed public URL |

Create a .env file in your working directory to set these:

PORT=6101
BLUEHIVE_API_KEY=BHSK-...

Developer Setup (from source)

1. Install & Start the Dashboard

git clone https://github.mieweb.com/hkonda/loco.git
cd loco
npm install
npm run dev

This starts two processes:

  • Vite dev server on port 6100 (dashboard + proxy)
  • Fastify API on port 6101 (backend)

On startup the terminal prints your working URLs:

  🌐 Loco Translation Manager

  Dashboard : http://<your-ip>:6100/loco/dashboard/
  CDN script: http://<your-ip>:6100/loco/cdn/loco.js
  API key   : <auto-generated>

  Paste into any page:

  <script src="http://<your-ip>:6100/loco/cdn/loco.js"></script>
  <script>Loco.init({ apiUrl: 'http://<your-ip>:6100/loco', apiKey: '<your-key>' });</script>

Open the Dashboard URL in your browser to access the Translation Manager.

2. Add the CDN Snippet to Your Page

Copy the snippet from the terminal output (or from Dashboard → Settings → CDN Script Snippet) and paste it into any HTML page you want to translate. When that page loads in a browser, Loco automatically discovers text nodes and sends them to the dashboard as "Pending" items.

3. Install the Chrome Extension (Optional)

The Chrome extension adds a side panel for in-context translation editing on any page running the Loco snippet.

  1. Open Chrome and go to chrome://extensions/
  2. Enable Developer mode (toggle in the top-right corner)
  3. Click Load unpacked
  4. Select the chrome-extension/ folder inside this repo
  5. The Loco Translation Editor extension should appear in your extensions list

Configure the Extension

  1. Click the Loco extension icon in the Chrome toolbar → Options (or right-click → Extension options)
  2. Fill in the two fields:
    • API Base URL — the same base URL from the snippet, e.g. http://<your-ip>:6100/loco
    • API Key — the API key from Dashboard → Settings
  3. Click Save Settings, then Test Connection to verify it works
  4. Navigate to any page running the Loco snippet, then click the extension icon to open the side panel

4. Test Pages

Several test pages are included and served during development:

| Page | URL | |---|---| | Server Mode Test | http://<your-ip>:6100/loco/dashboard/test-server-mode.html | | File Mode Test | http://<your-ip>:6100/loco/dashboard/test-file-mode.html | | Pattern Test | http://<your-ip>:6100/loco/dashboard/test-patterns.html | | Basic Test | http://<your-ip>:6100/loco/dashboard/test-page.html |

Open any server-mode test page — text nodes should appear in the dashboard under Pending within a few seconds.

5. Configure BlueHive AI (for AI Translations)

To use AI-powered translations, you need a BlueHive API key:

  1. Go to Dashboard → Settings
  2. Under BlueHive API Key, paste your key (starts with BHSK-...)
  3. Click Save

If you don't have a key, sign up at bluehive.com and generate one from your developer account.

6. Translation Workflow

  1. Pending — Newly discovered text appears here. Review and approve items you want to translate.
  2. Approved — Approved phrases are ready for translation. Use AI Translate to batch-translate with BlueHive, or edit translations manually.
  3. Export — From the Approved tab, click Export JSON to download a translation file for File Mode.
  4. Apply — On any page with the Loco snippet, call Loco.apply('zh-CN') in the browser console to see translations live.

Self-Hosting (Production)

Prerequisites

  • Node.js 20+
  • npm
  • Linux server with systemd (for production deployment)

Build & Run

git clone https://github.mieweb.com/hkonda/loco.git
cd loco
npm install
npm run build
npm start

Dashboard available at http://<your-ip>:6101/dashboard/

An API key is auto-generated on first run — find it in the dashboard under Settings.

To enable AI translations, add your BlueHive API key in the dashboard under Settings > BlueHive API Key.

Deploy with systemd

The included deploy.sh handles everything:

chmod +x deploy.sh

./deploy.sh install    # Build + install systemd service + start
./deploy.sh stop       # Stop service
./deploy.sh start      # Start service
./deploy.sh restart    # Restart service
./deploy.sh status     # Show status + recent logs
./deploy.sh logs       # Tail live logs
./deploy.sh uninstall  # Stop + remove service

After install, the script prints your dashboard URL and CDN script URL.


Using Loco in Your App

Server Mode

Server mode connects your site to a running Loco instance. It automatically discovers text on the page, sends it to the server for management, and applies translations in real-time.

<script src="https://your-loco-server.com/cdn/loco.js"></script>
<script>
  Loco.init({
    apiUrl: 'https://your-loco-server.com',
    apiKey: 'YOUR_API_KEY'
  });

  // Apply a language
  Loco.apply('fr');
</script>

What happens:

  1. loco.js scans the DOM and extracts all translatable text nodes
  2. Text nodes are sent to the Loco server and appear in the dashboard as "pending"
  3. You approve phrases, add languages, and translate (manually or with AI) in the dashboard
  4. Loco.apply('fr') fetches approved translations from the server and swaps text in the DOM
  5. A MutationObserver watches for new DOM nodes and registers them automatically

File Mode

File mode uses a static JSON file — no server connection needed. Export the JSON from the dashboard or create it by hand.

<script src="/path/to/loco.js"></script>
<script>
  Loco.init({ file: '/translations.json' });

  // Apply a language
  Loco.apply('zh-CN');

  // Optional: render a floating language switcher widget
  Loco.widget({ position: 'bottom-right' });
</script>

Translation JSON format:

{
  "languages": ["fr", "zh-CN"],
  "translations": {
    "fr": {
      "Hello": "Bonjour",
      "Sign up": "S'inscrire",
      "Welcome back, {{var:0}}": "Bon retour, {{var:0}}"
    },
    "zh-CN": {
      "Hello": "你好",
      "Sign up": "注册",
      "Welcome back, {{var:0}}": "欢迎回来,{{var:0}}"
    }
  }
}

You can export this file from the dashboard at any time (Translations → Export JSON).

Client API

Loco.init(config)          // Initialize (server mode or file mode)
Loco.apply('fr')           // Apply translations for a language → Promise
Loco.restore()             // Revert all text to original
Loco.rescan()              // Re-scan DOM for new text nodes
Loco.widget({ position })  // Render language switcher ('bottom-right', 'bottom-left', 'top-right', 'top-left')
Loco.textnodes()           // Get all discovered text nodes
Loco.stopScan()            // Pause MutationObserver
Loco.startScan()           // Resume MutationObserver

Variable Handling

Loco automatically detects dynamic values in text and preserves them across translations:

Original:  "You have 5 new messages"
Key:       "You have {{var:0}} new messages"
French:    "Vous avez {{var:0}} nouveaux messages"
Rendered:  "Vous avez 5 nouveaux messages"

Architecture

flowchart TB
    subgraph Your Website or App
        A[loco.js Client Script]
    end

    subgraph Loco Server
        B[Fastify API]
        C[SQLite Database]
        D[AI Translation Jobs]
        E[Dashboard SPA]
    end

    subgraph External
        F[BlueHive AI API]
    end

    A -->|Register text nodes & screenshots| B
    A -->|Fetch translations| B
    B <--> C
    E -->|Manage phrases & languages & prompts| B
    B -->|Queue translation jobs| D
    D -->|Send text & context| F
    F -->|Return translations| D
    D -->|Store results| C

How It Works

  1. Discover — The client script scans your page, extracts text nodes (respecting blocked/inline tag rules), and sends them to the server along with page context and screenshots
  2. Manage — In the dashboard, review pending phrases, approve them, add target languages, and configure AI prompt templates
  3. Translate — Run AI translation jobs that use page screenshots and context for accurate results, or edit translations manually
  4. Deliver — The client fetches approved translations and swaps DOM text in real-time. Or export a static JSON file for file mode

Tech Stack

| Layer | Technology | |---|---| | Client Script | Vanilla JavaScript (no dependencies) | | Dashboard | Svelte 4 + Tailwind CSS | | Server | Fastify + Node.js | | Database | SQLite (better-sqlite3, WAL mode) | | Build Tool | Vite | | AI | BlueHive API | | Deployment | systemd + deploy.sh |


Performance Benchmarks (Latest)

The performance suite compares Server Mode and File Mode at identical node counts.

Run:

npx playwright test tests/performance.spec.ts

Configuration used for results below:

  • ITERATIONS=11 total per test
  • first iteration is warm-up and discarded
  • reported averages use n=10 recorded samples

Collection (Loco.rescan — full DOM tree walk)

Server

| Nodes | Avg (ms) [n] | Min (ms) | Max (ms) | |---|---:|---:|---:| | 100 | 0.80 [n=10] | 0.4 | 1.9 | | 500 | 1.79 [n=10] | 1.5 | 2.3 | | 1000 | 17.06 [n=10] | 16.0 | 18.0 | | 3000 | 117.49 [n=10] | 115.6 | 118.2 | | 5000 | 217.77 [n=10] | 213.9 | 221.3 |

File

| Nodes | Avg (ms) [n] | Min (ms) | Max (ms) | |---|---:|---:|---:| | 100 | 0.42 [n=10] | 0.3 | 0.7 | | 500 | 1.48 [n=10] | 1.2 | 1.8 | | 1000 | 17.16 [n=10] | 16.6 | 18.2 | | 3000 | 121.34 [n=10] | 112.2 | 125.3 | | 5000 | 223.69 [n=10] | 218.9 | 228.5 |

Apply (Loco.apply)

Server

| Nodes | Avg (ms) [n] | Min (ms) | Max (ms) | |---|---:|---:|---:| | 100 | 7.45 [n=10] | 7.1 | 7.9 | | 500 | 15.56 [n=10] | 10.2 | 17.7 | | 1000 | 23.41 [n=10] | 17.1 | 25.3 | | 3000 | 29.18 [n=10] | 22.7 | 36.1 | | 5000 | 42.72 [n=10] | 39.7 | 44.8 |

File

| Nodes | Avg (ms) [n] | Min (ms) | Max (ms) | |---|---:|---:|---:| | 100 | 1.03 [n=10] | 0.5 | 1.6 | | 500 | 2.85 [n=10] | 1.1 | 3.8 | | 1000 | 5.92 [n=10] | 1.6 | 7.3 | | 3000 | 17.47 [n=10] | 9.5 | 20.0 | | 5000 | 22.96 [n=10] | 18.6 | 25.6 |

Notes:

  • Collection measures a full DOM rescan (TreeWalker + context computation), not just reading cached nodes.
  • Apply time remains low in both modes; file mode is fastest across all tested node counts.
  • Collection uses WeakMap caching for isAncestorBlocked, hasMixedContent, and buildContextTrace to avoid redundant ancestor walks.
  • Server-mode apply at 5000 nodes includes network latency; file mode is pure client-side.

Publishing an NPM Update

Use this checklist whenever you add new features or fixes and want to release a new version.

1. Make your changes

Work on main or a feature branch as normal. Run npm run dev to develop locally.

2. Bump the version

Edit package.json at the root — increment "version" following semver:

patch (1.0.3 → 1.0.4) — bug fixes, small tweaks
minor (1.0.3 → 1.1.0) — new backwards-compatible features
major (1.0.3 → 2.0.0) — breaking changes

3. Build the package

node scripts/build-npm.js

This compiles the TypeScript server, builds the Svelte dashboard (with the correct /dashboard/ base path), builds the CDN client bundles, and assembles everything into npm-package/.

4. Publish

cd npm-package
echo '//registry.npmjs.org/:_authToken=<your-npm-token>' > .npmrc
npm publish --access public
rm .npmrc

Get a token at npmjs.com → Access Tokens — use a Classic Automation token (bypasses 2FA).

5. Verify

npm install -g @hkonda/loco-translate@<new-version>
loco

Open http://localhost:6101/dashboard/ to confirm everything loads.


What the build script does

| Step | Command | Output | |---|---|---| | Compile server | tsc -p tsconfig.server.json | dist-server/ | | Build dashboard | vite build (with LOCO_VITE_BASE=/dashboard/) | dist/ | | Build CDN (minified) | vite build in client/ | public/loco.min.js | | Build CDN (unminified) | cross-env LOCO_UNMINIFIED=1 vite build in client/ | public/loco.js | | Assemble | copies all of the above + bin/loco.js + README.md | npm-package/ |

The npm-package/ directory is gitignored — never commit it directly.