PHPackages                             yuriidiachuk/laravel-typed-i18n - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Localization &amp; i18n](/categories/localization)
4. /
5. yuriidiachuk/laravel-typed-i18n

ActiveLibrary[Localization &amp; i18n](/categories/localization)

yuriidiachuk/laravel-typed-i18n
===============================

Generate TypeScript types from Laravel translation files

v1.1.0(today)01↑2900%MITPHPPHP ^8.2CI passing

Since Jun 19Pushed todayCompare

[ Source](https://github.com/YuriyDyachuk/laravel-typed-i18n)[ Packagist](https://packagist.org/packages/yuriidiachuk/laravel-typed-i18n)[ Docs](https://github.com/yuriidiachuk/laravel-typed-i18n)[ GitHub Sponsors](https://github.com/YuriiDiachuk)[ RSS](/packages/yuriidiachuk-laravel-typed-i18n/feed)WikiDiscussions main Synced today

READMEChangelog (3)Dependencies (13)Versions (4)Used By (0)

Generate TypeScript types from Laravel translation files
========================================================

[](#generate-typescript-types-from-laravel-translation-files)

[![Latest Version on Packagist](https://camo.githubusercontent.com/1ed0fd7e79d0b19c20807d0bd4b0e1c70f6489ce5a426b5c4c46d7df51f07cac/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f79757269696469616368756b2f6c61726176656c2d74797065642d6931386e2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/yuriidiachuk/laravel-typed-i18n)[![GitHub Tests Action Status](https://camo.githubusercontent.com/375112bebc60ebe53bf0b1621cc32b95e2bbdfdfca8cacdd719b016cc8edca10/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f79757269696469616368756b2f6c61726176656c2d74797065642d6931386e2f72756e2d74657374732e796d6c3f6272616e63683d6d61696e266c6162656c3d7465737473267374796c653d666c61742d737175617265)](https://github.com/yuriidiachuk/laravel-typed-i18n/actions?query=workflow%3Arun-tests+branch%3Amain)[![Total Downloads](https://camo.githubusercontent.com/f44723db7a4b8debd20265e76de3b70093f2ef7b4ce9a6eef762fe9cc7eabb53/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f79757269696469616368756b2f6c61726176656c2d74797065642d6931386e2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/yuriidiachuk/laravel-typed-i18n)

Turn your Laravel translation files into a TypeScript declaration file, so your frontend gets **autocomplete on translation keys** and **type-checked parameters**, including a required `count` on pluralized strings. Zero runtime: the package emits types only and stays out of the way of whatever `trans`/`$t`/`__` helper you already use.

Requirements
------------

[](#requirements)

- PHP 8.2+
- Laravel 11 or 12

Installation
------------

[](#installation)

```
composer require yuriidiachuk/laravel-typed-i18n --dev
```

Optionally publish the config:

```
php artisan vendor:publish --tag="typed-i18n-config"
```

Usage
-----

[](#usage)

```
php artisan typed-i18n:generate
```

Given `lang/en/messages.php`:

```
return [
    'welcome' => 'Hello :name',
    'cart' => [
        'items' => '{1} :count item|[2,*] :count items',
    ],
];
```

and `lang/en.json`:

```
{ "Save": "Save" }
```

the command writes (default `resources/js/types/translations.d.ts`):

```
// translations.d.ts
// GENERATED by laravel-typed-i18n. Do not edit by hand.

export interface Translations {
  'Save': {};
  'cart.items': { count: number };
  'messages.welcome': { name: string | number };
}

export type TranslationKey = keyof Translations;

export type EmptyParamKeys = {
  [K in TranslationKey]: keyof Translations[K] extends never ? K : never;
}[TranslationKey];
```

### Wiring it to your translator

[](#wiring-it-to-your-translator)

The `Translations` interface maps each key to its required params. Wrap your existing helper once to get full type safety and autocomplete:

```
import type { Translations, TranslationKey, EmptyParamKeys } from '@/types/translations';

export function t(key: K): string;
export function t(key: K, params: Translations[K]): string;
export function t(key: TranslationKey, params?: Record): string {
  return translate(key, params); // delegate to your runtime (laravel-vue-i18n, i18next, Inertia, etc.)
}

t('messages.welcome', { name: 'Yurii' }); // ✅ name required & autocompleted
t('messages.welcome');                    // ❌ TS error: missing params
t('cart.items', { count: 3 });            // ✅ count: number required on plural keys
t('Save');                                // ✅ no params
```

What it parses
--------------

[](#what-it-parses)

- `lang/{locale}/*.php` group files become `messages.auth.login` (dot notation, nested arrays flattened)
- `lang/{locale}.json` uses the phrase as the key, verbatim
- `lang/vendor/{package}/{locale}/*.php` becomes `package::group.key` (toggle with `include_vendor`)
- `:placeholder` tokens become required params, case-normalized (`:name`/`:Name`/`:NAME` are one param)
- pluralized strings (`apple|apples`, `{0}...|[2,*]...`) get a required `count: number`

### Locale drift detection

[](#locale-drift-detection)

The reference locale (config `default_locale`, falling back to `app.fallback_locale`) defines the types. Every other locale is compared against it and missing or extra keys are reported when you run the command:

```
WARN  Locale [de] is missing 2 key(s) present in [en]: cart.items, messages.welcome

```

Keeping types in sync
---------------------

[](#keeping-types-in-sync)

The generated file is a build artifact. Regenerate it whenever translations change instead of editing it by hand. A few common ways to wire that in:

- Run the command before your frontend build, for example in a `composer` or `npm` script.
- Add it to a pre-commit hook so the file never lags behind the lang files.
- Run `typed-i18n:generate --check` in CI. It compares the committed file against freshly generated types and exits non-zero (without writing) when they differ, so a translation changed without regenerating fails the build:

    ```
    php artisan typed-i18n:generate --check
    ```

Whether you commit the file or generate it on the fly is up to you. Committing it keeps diffs visible in review; generating it on the fly keeps it out of version control.

Configuration
-------------

[](#configuration)

```
return [
    'lang_path'      => null,  // null uses lang_path()
    'default_locale' => null,  // null uses config('app.fallback_locale')
    'locales'        => null,  // null auto-discovers locales from the lang path
    'output'         => null,  // null uses resource_path('js/types/translations.d.ts')
    'include_vendor' => true,
];
```

CLI options: `--locale=`, `--output=`, and `--check` (verify only, never writes).

Testing
-------

[](#testing)

```
composer test
```

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

41

—

FairBetter than 87% of packages

Maintenance100

Actively maintained with recent releases

Popularity2

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity48

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

3

Last Release

0d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/56764630?v=4)[mrAnderson](/maintainers/YuriyDyachuk)[@YuriyDyachuk](https://github.com/YuriyDyachuk)

---

Top Contributors

[![YuriyDyachuk](https://avatars.githubusercontent.com/u/56764630?v=4)](https://github.com/YuriyDyachuk "YuriyDyachuk (8 commits)")

---

Tags

laraveli18ntranslationstypescripttypescodegenYuriiDiachuklaravel-typed-i18n

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

Type Coverage Yes

### Embed Badge

![Health badge](/badges/yuriidiachuk-laravel-typed-i18n/health.svg)

```
[![Health](https://phpackages.com/badges/yuriidiachuk-laravel-typed-i18n/health.svg)](https://phpackages.com/packages/yuriidiachuk-laravel-typed-i18n)
```

###  Alternatives

[spatie/laravel-pdf

Create PDFs in Laravel apps

1.0k4.3M42](/packages/spatie-laravel-pdf)[osama-98/laravel-enum-translatable

A Laravel package that provides translatable enum functionality with easy-to-use methods for working with enum values and their translations

561.1k](/packages/osama-98-laravel-enum-translatable)[outhebox/laravel-translations

Manage your Laravel translations with a beautiful UI. Add, edit, delete, import, and export translations with ease.

81196.3k](/packages/outhebox-laravel-translations)[rawilk/profile-filament-plugin

Profile &amp; MFA starter kit for filament.

3913.7k](/packages/rawilk-profile-filament-plugin)[elegantly/laravel-translator

All on one translations management for Laravel

6326.3k](/packages/elegantly-laravel-translator)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
