@gringow/gringow
v0.3.1
Published
AI-powered translation library for template strings using multiple LLM providers
Downloads
491
Maintainers
Readme
@gringow/gringow
AI-powered translation library for template strings using multiple LLM providers via multi-llm-ts. 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
- 🔌 Multiple LLM providers (OpenAI default, Anthropic, Gemini, Groq, Mistral, Ollama, and more)
- ⚙️ Config-driven behavior through
gringow.config.* - 📦 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, ['Alice', 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,
},
sourceLanguage: 'en-US',
defaultLanguage: 'pt-BR',
languages: ['pt-BR', 'fr-CA'],
llm: {
provider: 'openai',
apiKey: process.env.OPENAI_API_KEY,
model: 'gpt-4o-mini',
temperature: 1.0,
sleep: 0,
},
globby: './src/**/*.{js,jsx,ts,tsx}',
}Example: Using Gemini
// gringow.config.js
export default {
llm: {
provider: 'gemini',
apiKey: process.env.GEMINI_API_KEY,
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 {
llm: {
provider: 'anthropic',
apiKey: process.env.ANTHROPIC_API_KEY,
model: 'claude-3-5-sonnet-20241022',
temperature: 0.7,
},
}Prompt Customization
Fine-tune LLM behavior with prompt options:
export default {
llm: {
provider: 'openai',
apiKey: process.env.OPENAI_API_KEY,
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
OpenAI (Default)
Uses OpenAI through multi-llm-ts. Requires API key.
// gringow.config.js
export default {
llm: {
provider: 'openai',
apiKey: process.env.OPENAI_API_KEY,
model: 'gpt-4o-mini',
},
}Pros: Broad model availability, simple default setup
Cons: API costs, requires internet
Anthropic
Uses Claude models via Anthropic API. Requires API key.
// gringow.config.js
export default {
llm: {
provider: 'anthropic',
apiKey: process.env.ANTHROPIC_API_KEY,
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 {
llm: {
provider: 'gemini',
apiKey: process.env.GEMINI_API_KEY,
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
awaitedConfig, // Access resolved configuration
isLocalConfigFound, // Check if local config exists
getConfigSource, // Get config file path
} from '@gringow/gringow'import { interpolateTemplate } from '@gringow/gringow/browser'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:watchRelated Packages
Gringow provides a complete ecosystem for AI-powered translation:
- @gringow/gringow - Core translation library
- @gringow/gringow-vite - Vite plugin for build-time extraction
- @gringow/gringow-react - React hooks and components
- @gringow/gringow-shadow - Web Component layer
- @gringow/gringow-cli - CLI tool
- @gringow/gringow-nextjs - Next.js plugin (experimental)
Related Resources
License
MIT © Renato Gaspar
Questions or Issues? Open an issue on GitHub
