Package Exports
- @geenius/i18n
- @geenius/i18n/cloudflareKV
- @geenius/i18n/convex
- @geenius/i18n/convex/convex.config
- @geenius/i18n/memory
- @geenius/i18n/neon
- @geenius/i18n/react
- @geenius/i18n/react-ant
- @geenius/i18n/react-ant/styles.css
- @geenius/i18n/react-chakra
- @geenius/i18n/react-chakra/styles.css
- @geenius/i18n/react-css
- @geenius/i18n/react-css/styles.css
- @geenius/i18n/react-daisyui
- @geenius/i18n/react-daisyui/styles.css
- @geenius/i18n/react-heroui
- @geenius/i18n/react-heroui/styles.css
- @geenius/i18n/react-mantine
- @geenius/i18n/react-mantine/styles.css
- @geenius/i18n/react-mui
- @geenius/i18n/react-mui/styles.css
- @geenius/i18n/react-native
- @geenius/i18n/react-shadcn
- @geenius/i18n/react-shadcn/styles.css
- @geenius/i18n/solidjs
- @geenius/i18n/solidjs-ark
- @geenius/i18n/solidjs-ark/styles.css
- @geenius/i18n/solidjs-css
- @geenius/i18n/solidjs-css/styles.css
- @geenius/i18n/solidjs-kobalte
- @geenius/i18n/solidjs-kobalte/styles.css
- @geenius/i18n/solidjs-solidui
- @geenius/i18n/solidjs-solidui/styles.css
Readme
@geenius/i18n
Type-safe internationalization for Geenius applications. The package provides shared locale metadata, translation lookup, interpolation, pluralization, runtime locale switching, RTL helpers, Intl formatting, framework-native UI bindings, and provider-backed translation persistence.
This README documents the current launch support surface: root shared exports, 15 UI variants, and four DB providers. Deeper architecture, launch-roadmap, and tier details live in the package docs:
Installation
pnpm add @geenius/i18nBasic Usage
import type { ReactNode } from "react";
import { createI18nConfig } from "@geenius/i18n";
import { ReactI18nProvider, LocaleSwitcher, useI18n } from "@geenius/i18n/react";
const config = createI18nConfig()
.withDefaultLocale("en")
.withSupportedLocales(["en", "ar"])
.withFallbackLocale("en")
.build();
const translations = {
"home.title": "Home",
"home.cta": "Start",
};
function Toolbar() {
const { locale, setLocale } = useI18n();
return (
<LocaleSwitcher
locales={["en", "ar"]}
current={locale}
onChange={setLocale}
/>
);
}
export function App({ children }: { children: ReactNode }) {
return (
<ReactI18nProvider config={config} translations={translations}>
<Toolbar />
{children}
</ReactI18nProvider>
);
}React CSS Usage
import { useState } from "react";
import {
CurrencyField,
ReactI18nProvider,
LocaleSwitcher,
useI18n,
} from "@geenius/i18n/react-css";
const translations = {
"billing.total": "Total",
};
function BillingControls() {
const { locale, setLocale } = useI18n();
const [amount, setAmount] = useState<number | null>(199);
return (
<section className="gn-i18n-admin__section">
<LocaleSwitcher
current={locale}
locales={["en", "de"]}
onChange={setLocale}
/>
<CurrencyField
currency="USD"
label="Invoice total"
onChange={setAmount}
value={amount}
/>
</section>
);
}
export function BillingPanel() {
return (
<ReactI18nProvider locale="en" translations={translations}>
<BillingControls />
</ReactI18nProvider>
);
}React Native Usage
import { Text, View } from "react-native";
import {
ReactI18nProvider,
LocaleSwitcher,
useI18n,
} from "@geenius/i18n/react-native";
const messages = {
"home.title": "Home",
};
function NativeToolbar() {
const { locale, setLocale } = useI18n();
return (
<LocaleSwitcher
accessibilityLabel="Select app locale"
current={locale}
locales={["en", "ar"]}
onChange={setLocale}
testID="settings-locale-switcher"
/>
);
}
export function NativeApp() {
return (
<ReactI18nProvider locale="en" messages={messages}>
<View testID="home-screen">
<NativeToolbar />
<Text accessibilityLabel="Current screen title">Home</Text>
</View>
</ReactI18nProvider>
);
}Public Imports
Shared helpers come from the package root. Framework bindings and persistence
providers come from explicit public subpaths. There is no public ./shared
subpath.
import {
ALL_LOCALES,
DEFAULT_LOCALE,
DEFAULT_LOCALE_STORAGE_KEY,
DEFAULT_NAMESPACE,
LOCALE_INFO,
createI18nConfig,
createI18nDiagnostics,
createNamespaceLoader,
createTranslationLoader,
createTypedTranslator,
detectLocale,
formatCurrency,
formatDate,
formatNumber,
getPersistedLocale,
getDirection,
interpolate,
i18nConfigSchema,
i18nPresets,
isLocale,
isRTL,
loadNamespace,
localeSchema,
readBrowserPersistedLocale,
plural,
t,
toI18nError,
toI18nIntegrationError,
translationDictSchema,
} from "@geenius/i18n";
import { ReactI18nProvider, LocaleSwitcher, useI18n, useReactT } from "@geenius/i18n/react";
import { ReactI18nProvider as ReactCssProvider } from "@geenius/i18n/react-css";
import {
SolidI18nProvider,
createI18n,
createTranslations,
} from "@geenius/i18n/solidjs";
import { SolidI18nProvider as SolidCssProvider } from "@geenius/i18n/solidjs-css";
import { schema, i18nTables, upsertTranslation } from "@geenius/i18n/convex";
import componentConfig from "@geenius/i18n/convex/convex.config";
import { createNeonI18nStore, i18nTranslations } from "@geenius/i18n/neon";
import { createCloudflareKvI18nStore } from "@geenius/i18n/cloudflareKV";
import { createMemoryI18nStore } from "@geenius/i18n/memory";Use cloudflareKV for provider ids, variants.json driver values, docs, and
consumer imports. Lowercase slugs such as cloudflare-kv are not launch-axis
tokens.
API Summary
Root @geenius/i18n exports the framework-agnostic surface:
- Locale metadata:
ALL_LOCALES,LOCALE_INFO,RTL_LOCALES,SUPPORTED_LOCALES - Defaults:
DEFAULT_LOCALE,DEFAULT_NAMESPACE,DEFAULT_LOCALE_STORAGE_KEY,DEFAULT_TRANSLATIONS_BASE_URL,DEFAULT_CACHE_DURATION_MS - Locale helpers:
detectLocale,getDirection,getLocaleDisplayLabel,getPersistedLocale,isLocale,isRTL - Locale storage:
readBrowserPersistedLocale,readPersistedLocaleFromStorage,writeBrowserPersistedLocale,writePersistedLocaleToStorage - Translation helpers:
t,interpolate,plural,flattenDict,createTypedTranslator - Formatting:
formatDate,formatNumber,formatCurrency - Config and loading:
createI18nConfig,I18nConfigBuilder,i18nPresets,createTranslationLoader,createNamespaceLoader,loadNamespace - Diagnostics:
createI18nDiagnostics,createI18nLoggerScope,logMissingKeyDiagnostic,mergeI18nDiagnosticContext,normalizeI18nDiagnosticContext - Validators:
localeSchema,i18nConfigSchema,translationDictSchema,translationEntrySchema,bulkImportTranslationsInputSchema,missingKeySchema,localeStatSchema - Errors:
I18nError,I18nConfigError,TranslationNotFoundError,LocaleNotSupportedError,TranslationLoadError,toI18nError,toI18nIntegrationError
UI subpaths export framework-specific providers, hooks or primitives, components, fields, and admin pages. Styling helpers and styling-only type aliases stay variant-local.
DB provider subpaths expose the same translation and missing-key contract: translation lookup/listing, upsert/delete/import, locale stats, missing-key reporting, missing-key listing, and missing-key clearing.
Variants
| Subpath | Status | Purpose |
|---|---|---|
@geenius/i18n |
in scope | Shared locale metadata, helpers, config, loaders, errors, and types |
@geenius/i18n/react |
in scope | React provider, hooks, components, fields, and admin pages |
@geenius/i18n/react-css |
in scope | React bindings styled with BEM classes and canonical --gn-* CSS tokens |
@geenius/i18n/solidjs |
in scope | SolidJS provider primitives, components, fields, and admin pages |
@geenius/i18n/solidjs-css |
in scope | SolidJS bindings styled with BEM classes and canonical --gn-* CSS tokens |
@geenius/i18n/react-shadcn |
in scope | React bindings rendered with shadcn/ui and Radix primitives |
@geenius/i18n/react-ant |
in scope | React bindings rendered with Ant Design controls |
@geenius/i18n/react-chakra |
in scope | React bindings rendered with Chakra UI components |
@geenius/i18n/react-mui |
in scope | React bindings rendered with MUI components |
@geenius/i18n/react-mantine |
in scope | React bindings rendered with Mantine components |
@geenius/i18n/react-heroui |
in scope | React bindings rendered with HeroUI components |
@geenius/i18n/react-daisyui |
in scope | React bindings rendered with DaisyUI classes and primitives |
@geenius/i18n/react-native |
in scope | React Native provider, controls, hooks, and accessibility selectors |
@geenius/i18n/solidjs-ark |
in scope | SolidJS bindings rendered with Ark UI primitives |
@geenius/i18n/solidjs-kobalte |
in scope | SolidJS bindings rendered with Kobalte primitives |
@geenius/i18n/solidjs-solidui |
in scope | SolidJS bindings rendered with Solid UI primitives |
@geenius/i18n/convex |
in scope | Convex schema, validators, typed queries, and typed mutations |
@geenius/i18n/neon |
in scope | Native @neondatabase/serverless SQL migrations and typed store helpers |
@geenius/i18n/cloudflareKV |
in scope | Cloudflare Workers KV translation store with TTL-aware missing-key records |
@geenius/i18n/memory |
in scope | In-process provider for tests, Storybook fixtures, and local demos |
All 15 launch UI variants and all four DB providers are part of the active manifest, build, lint, type-check, Storybook, and test matrices.
Provider Notes
Convex and Neon persist PRD-backed i18n_translations and
i18n_missing_keys data. Cloudflare KV exposes equivalent public operations
over key/value storage and does not claim relational query semantics. The memory
provider is ephemeral and intended for local development, tests, and fixtures.
import { defineApp } from "convex/server";
import componentConfig from "@geenius/i18n/convex/convex.config";
const app = defineApp();
app.use(componentConfig);
export default app;import { createMemoryI18nStore } from "@geenius/i18n/memory";
const store = createMemoryI18nStore();
await store.upsertTranslation({
locale: "en",
namespace: "common",
key: "cta",
value: "Start",
});
const entry = await store.getTranslation({
locale: "en",
namespace: "common",
key: "cta",
});Storybook
The active Storybook apps use the stock Storybook v10 shape and consume
@geenius/storybook preset, manager, and preview helpers.
pnpm --filter ./apps/storybook-react dev
pnpm --filter ./apps/storybook-react-css dev
pnpm --filter ./apps/storybook-solidjs dev
pnpm --filter ./apps/storybook-solidjs-css dev
pnpm --filter ./apps/storybook-react-shadcn dev
pnpm --filter ./apps/storybook-react-ant dev
pnpm --filter ./apps/storybook-react-chakra dev
pnpm --filter ./apps/storybook-react-mui dev
pnpm --filter ./apps/storybook-react-mantine dev
pnpm --filter ./apps/storybook-react-heroui dev
pnpm --filter ./apps/storybook-react-daisyui dev
pnpm --filter ./apps/storybook-react-native dev
pnpm --filter ./apps/storybook-solidjs-ark dev
pnpm --filter ./apps/storybook-solidjs-kobalte dev
pnpm --filter ./apps/storybook-solidjs-solidui dev- React: http://localhost:6100
- React CSS: http://localhost:6101
- SolidJS: http://localhost:6102
- SolidJS CSS: http://localhost:6103
The reference ports above are stable for the four reference apps. Library and native Storybook apps follow their app-level package scripts and assigned review ports.
Testing
The package matrix is driven by variants.json. Scripts
should read that manifest instead of hardcoding variant or provider lists.
pnpm lint
pnpm lint:apps
pnpm lint:pub
pnpm type-check
pnpm test
pnpm test:e2e
pnpm test:coverage
pnpm test:storybook:build
pnpm test:storybook
pnpm test:visual
pnpm test:visual:update
pnpm size
pnpm audit:supply-chain
pnpm test:license
pnpm test:gauntlet
pnpm test:allpnpm test:gauntlet is the PR-blocking package gate. pnpm test:all runs the
gauntlet plus e2e, a11y, visual, performance, and coverage reporting for the
current scoped matrix. Use pnpm test:visual:update only after reviewing
intentional visual baseline changes.
Contributing
Add or re-enable variants through variants.json first, then make the matching
package and Storybook app pass the same export, type, packed-smoke, and parity
contracts as the active variants. All 15 documented UI variants are launch
scope for this package.
Storybook apps must use the V2 stock layout under apps/storybook-<variant>/:
.storybook/main.ts, .storybook/manager.ts, .storybook/preview.ts, and
typed stories. Do not add a Vite shell app, custom registry, or legacy SPA
bootstrap.
License
@geenius/i18n is distributed under the Functional Source License 1.1 with a
future Apache 2.0 grant. Commercial use follows the proprietary Geenius
licensing terms described in LICENSE.