@gringow/gringow
v0.2.0
Published
AI-powered translation library for template strings using multiple LLM providers
Downloads
392
Maintainers
Readme
@gringow/gringow
AI-powered translation library for template strings using multiple LLM providers (Hugging Face, Anthropic, Gemini). Gringow provides smart caching, deterministic content hashing, and seamless integration for modern JavaScript/TypeScript projects.
Features
- 🌍 Multi-language translation using LLM providers
- 🏷️ Tagged template literal syntax for inline translations
- 💾 Smart caching with content-based hashing
- 🔌 Three LLM providers: Hugging Face (local), Anthropic, Gemini
- 🚀 Zero configuration - works out of the box with Hugging Face
- 📦 Optimized builds via Vite/Next.js plugins
Installation
npm install @gringow/gringow
# or
pnpm add @gringow/gringow
# or
yarn add @gringow/gringowQuick Start
import Gringow from '@gringow/gringow'
// Simple string translation
const { cacheId, translation } = await Gringow`Hello world`
console.log(translation.translation)
// => { "pt-BR": "Olá mundo", "fr-CA": "Bonjour le monde" }
// Template string with dynamic values
const name = 'John'
const { translation: result } = await Gringow`Welcome, ${name}!`
console.log(result.translation)
// => { "pt-BR": "Bem-vindo, John!", "fr-CA": "Bienvenue, John!" }Usage Examples
Basic Translation
import Gringow from '@gringow/gringow'
// Translate a static string
const { translation } = await Gringow`Hello world`
console.log(translation.translation['pt-BR']) // "Olá mundo"Dynamic Content
// Template literals are flattened before hashing - dynamic values preserved
const user = { name: 'Alice', role: 'admin' }
const { translation } = await Gringow`User ${user.name} has ${user.role} privileges`
console.log(translation.translation['pt-BR'])
// => "Usuário Alice tem privilégios de admin"Cache Management
import Gringow, { rebuild, checkCache } from '@gringow/gringow'
const { cacheId } = await Gringow`Hello world`
// Check if translation exists in cache
const cached = await checkCache(cacheId)
console.log(cached) // GringowCacheItem or undefined
// Force re-translation by rebuilding cache entry
const refreshed = await rebuild(cacheId)
console.log(refreshed.translation.translation)Browser Usage
For client-side interpolation without Node.js dependencies:
import { interpolateTemplate } from '@gringow/gringow/browser'
const template = 'Hello {name}, you have {count} messages'
const result = interpolateTemplate(template, { name: 'Alice', count: 5 })
console.log(result) // "Hello Alice, you have 5 messages"Configuration
Gringow uses cosmiconfig to load configuration from your project root. Supported formats: gringow.config.js, gringow.config.mjs, gringow.config.json, or a gringow field in package.json.
Default Configuration
// gringow.config.js
export default {
debug: false,
log: { level: 'info' },
cache: {
dir: './gringow',
file: 'gringow.json',
prefix: 'grw',
write: true,
},
keys: {
anthropicApiKey: process.env.ANTHROPIC_API_KEY,
geminiApiKey: process.env.GEMINI_API_KEY,
},
sourceLanguage: 'en-US',
languages: ['pt-BR', 'fr-CA'],
llm: {
choice: 'huggingface', // 'huggingface' | 'anthropic' | 'gemini'
model: 'Xenova/nllb-200-distilled-600M',
temperature: 1.0,
sleep: 0,
},
globby: './src/**/*.{js,jsx,ts,tsx}',
}Example: Using Gemini
// gringow.config.js
export default {
keys: {
geminiApiKey: process.env.GEMINI_API_KEY,
},
llm: {
choice: 'gemini',
model: 'gemini-2.0-flash',
prePromptAppend: 'Please respond in a friendly tone.',
},
languages: ['es-ES', 'de-DE', 'ja-JP'],
}Example: Using Anthropic
// gringow.config.js
export default {
keys: {
anthropicApiKey: process.env.ANTHROPIC_API_KEY,
},
llm: {
choice: 'anthropic',
model: 'claude-3-5-sonnet-20241022',
temperature: 0.7,
},
}Prompt Customization
Fine-tune LLM behavior with prompt options:
export default {
llm: {
choice: 'huggingface',
prePrompt: 'Translate the following text:', // Default prompt prefix
postPrompt: 'Ensure translations are natural.', // Additional context
prePromptAppend: 'Use formal language.', // Appended to pre-prompt
postPromptPrepend: 'Maintain original formatting.', // Prepended to post-prompt
prePromptReplace: 'Custom instruction here', // Replaces entire pre-prompt
},
}LLM Providers
Hugging Face (Default)
Runs local models via @huggingface/transformers. No API key required.
// gringow.config.js
export default {
llm: {
choice: 'huggingface',
model: 'Xenova/nllb-200-distilled-600M', // Multilingual translation model
},
}Pros: Free, private, offline-capable
Cons: Slower first run (model download), higher memory usage
Anthropic
Uses Claude models via Anthropic API. Requires API key.
// gringow.config.js
export default {
keys: {
anthropicApiKey: process.env.ANTHROPIC_API_KEY,
},
llm: {
choice: 'anthropic',
model: 'claude-3-5-sonnet-20241022',
},
}Pros: High-quality translations, fast
Cons: API costs, requires internet
Gemini
Uses Google's Gemini models. Requires API key.
// gringow.config.js
export default {
keys: {
geminiApiKey: process.env.GEMINI_API_KEY,
},
llm: {
choice: 'gemini',
model: 'gemini-2.0-flash',
},
}Pros: Fast, cost-effective
Cons: API costs, requires internet
API Reference
Core Functions
Gringow(strings, ...values): Promise<GringowResponse>
Main translation function. Accepts tagged template literals or plain strings.
const result = await Gringow`Hello ${name}`Returns: Promise<GringowResponse> with { cacheId, translation }
rebuild(cacheId: string): Promise<GringowResponse>
Re-translates a cached entry using the current LLM configuration.
const refreshed = await rebuild('grw_abc123')Cache Helpers
import {
checkCache, // Check if cacheId exists
getCache, // Get entire cache object
getOrCreateCache,// Get cache or create empty one
writeCacheToDisk,// Manually write cache entry
deleteCacheItem, // Remove cache entry
clearCache, // Clear all cache entries
} from '@gringow/gringow'Utilities
import {
createCacheId, // Generate cache ID from string
flatTemplateString, // Flatten template literal to string
interpolateTemplate, // Browser-safe interpolation (from /browser export)
awaitedConfig, // Access resolved configuration
isLocalConfigFound, // Check if local config exists
getConfigSource, // Get config file path
} from '@gringow/gringow'Type Definitions
type GringowTranslation = Record<string, string>
type GringowCacheItem = {
original: string
translation: GringowTranslation
append?: string
prepend?: string
rebuild?: boolean
}
type GringowResponse = {
cacheId: string
translation: GringowCacheItem
}How It Works
- Input Processing: Template strings are flattened to plain text (preserving dynamic values)
- Cache ID Generation: Content-based hash created using
createCacheId() - Cache Lookup: Check
./gringow/gringow.jsonfor existing translation - LLM Query: If not cached, request translation from configured provider
- Response Parsing: Parse provider response to
GringowCacheItemformat - Cache Storage: Write to disk when
cache.writeistrue
Example cache structure:
{
"grw_a1b2c3": {
"original": "Hello world",
"translation": {
"pt-BR": "Olá mundo",
"fr-CA": "Bonjour le monde"
}
}
}Development
# Install dependencies
pnpm install
# Build the package
pnpm run build
# Run tests
pnpm run test
# Watch mode
pnpm run test:watchIntegrations
Gringow has official integrations for modern web frameworks:
- @gringow/cli - Command-line interface for cache management and translations
- @gringow/gringow-vite - Vite plugin for build-time translation extraction
- @gringow/gringow-react - React hooks and components
- @gringow/gringow-shadow - Web Component layer (vanilla JS)
- @gringow/gringow-nextjs - Next.js plugin (experimental)
Related Resources
License
MIT © Renato Gaspar
Questions or Issues? Open an issue on GitHub
