PHPackages                             martinpham/laravel-type-generator - 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. martinpham/laravel-type-generator

ActiveLibrary

martinpham/laravel-type-generator
=================================

Generate types from Laravel routes and Laravel Eloquent/Laravel Data objects.

1.5.9(8mo ago)2133MITPHP

Since Aug 10Pushed 1mo agoCompare

[ Source](https://github.com/MartinPham/laravel-type-generator)[ Packagist](https://packagist.org/packages/martinpham/laravel-type-generator)[ RSS](/packages/martinpham-laravel-type-generator/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (6)Versions (15)Used By (0)

**TLDR:** If you've ever wanted fully type-safe integration between your Laravel backend and your frontend (whether that's API consumers or Inertia.js apps), this package might save you a ton of time.

What It Does
------------

[](#what-it-does)

The `laravel-type-generator` package scans your Laravel routes, controllers, models, DTOs, and their properties, methods, docblocks, and PHP source code. It then automatically generates:

- TypeScript types from your Laravel routes
- OpenAPI specifications for API documentation
- Swagger UI to visualize and interact with your OpenAPI spec
- Inertia.js type generation
- Accurate handling of pagination, collections, and complex return types

*(More transformers are coming soon!)*

Think of it as a bridge that keeps your Laravel backend and frontend perfectly synchronized with types.

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

[](#installation)

```
composer require martinpham/laravel-type-generator
```

Publish the config:

```
php artisan vendor:publish --tag="type-generator"
```

Then run:

```
php artisan types:generate
```

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

[](#configuration)

The package is flexible. In the config file, you can customize what gets generated and where it goes. Here's a practical example showing how to generate:

- An OpenAPI specification JSON file for routes matching `/_api/*`
- TypeScript types for Inertia.js routes and template variables, for controllers matching `App\Http\Controllers\Web\*`

```
'route_prefixes' => [
    'uri:_api' => [
        'output' => resource_path('api/openapi.json'),
        'class' => 'MartinPham\TypeGenerator\Writers\OpenAPI\OpenAPI',
        'options' => [
            'openapi' => '3.0.2',
            'title' => 'OpenAPI',
            'version' => '1.0.0'
        ]
    ],
    'controller:App\Http\Controllers\Web\\' => [
        'output' => resource_path('js/types/inertia-routes.ts'),
        'class' => 'MartinPham\TypeGenerator\Writers\Inertia\Inertia',
    ],
],
```

Example: How Your Controller Becomes Typed API Specs
----------------------------------------------------

[](#example-how-your-controller-becomes-typed-api-specs)

Let's say you have a simple controller method like this:

```
class PlaygroundApiController extends Controller
{
    public function findUser(User $user): User
    {
        return $user;
    }
}
```

### Here's what happens under the hood:

[](#heres-what-happens-under-the-hood)

1. The package analyzes the `findUser` method's input parameter (`User $user`) and return type (`User`).
2. It automatically generates an OpenAPI operation for this route with `$user` as a parameter.
3. It creates a `User` schema for both request and response types.
4. Since your User model has relationships (like Address and Country), it recursively generates schemas for those related models too — so your OpenAPI spec and TypeScript types reflect the complete data structure.

This means your frontend gets fully typed models, including nested relationships, without any extra manual work!

[![OpenAPI](https://camo.githubusercontent.com/2dda1408ce1b4f5601c4e1bf1f74d4a3c4e60ceb178a1d04e4b572c4d56b5cb0/68747470733a2f2f6465762d746f2d75706c6f6164732e73332e616d617a6f6e6177732e636f6d2f75706c6f6164732f61727469636c65732f69656531677163307974706b31663378356774782e706e67)](https://camo.githubusercontent.com/2dda1408ce1b4f5601c4e1bf1f74d4a3c4e60ceb178a1d04e4b572c4d56b5cb0/68747470733a2f2f6465762d746f2d75706c6f6164732e73332e616d617a6f6e6177732e636f6d2f75706c6f6164732f61727469636c65732f69656531677163307974706b31663378356774782e706e67)

Seamless Integration with Orval for Type-Safe API Clients &amp; Inertia template
--------------------------------------------------------------------------------

[](#seamless-integration-with-orval-for-type-safe-api-clients--inertia-template)

Once `laravel-type-generator` creates your OpenAPI spec, you can feed it directly into Orval to automatically generate TypeScript types and API clients.

Here's what Orval would produce from the generated spec:

```
export interface User {
  id?: number;
  name?: string;
  email?: string;
  role?: string;
  address?: Address;
}

export interface Address {
  id?: number;
  street?: string;
  country?: Country;
}

export interface Country {
  id?: number;
  name?: string;
  code?: string;
}

export const apiPlaygroundUsers = (
  user: string,
  options?: AxiosRequestConfig
): Promise => {
  return axios.get(`/_api/playground/findUser/${user}`, options);
};
```

### What this means for you:

[](#what-this-means-for-you)

- Your frontend knows exactly what data to expect — including nested objects like Address and Country
- Your API calls are fully typed, with correct parameter and response types
- No more guesswork or brittle `any` types when consuming your Laravel backend APIs

This creates a tight feedback loop between your backend and frontend, boosting developer confidence and reducing bugs from mismatched data structures.

### Inertia template

[](#inertia-template)

On Inertia side, you will receive exactly the types which were returned by the route

[![Inertia](https://camo.githubusercontent.com/2664b196543cbfa6e87a23741d74caddaeb156e18c397df30e85f2b593ad8f06/68747470733a2f2f6465762d746f2d75706c6f6164732e73332e616d617a6f6e6177732e636f6d2f75706c6f6164732f61727469636c65732f367679667367676667317a7437306f7a326f61652e706e67)](https://camo.githubusercontent.com/2664b196543cbfa6e87a23741d74caddaeb156e18c397df30e85f2b593ad8f06/68747470733a2f2f6465762d746f2d75706c6f6164732e73332e616d617a6f6e6177732e636f6d2f75706c6f6164732f61727469636c65732f367679667367676667317a7437306f7a326f61652e706e67)

Full Support for Various Data Types
-----------------------------------

[](#full-support-for-various-data-types)

The `laravel-type-generator` isn't limited to just Eloquent models. It also supports:

- Plain PHP classes
- Laravel Data objects (like from Spatie's laravel-data package)
- API Resources
- Your own custom-defined docblocks

To give you more control over the generated OpenAPI spec, you can use special docblock annotations in your controller methods:

- `@id` — Overrides the default operationId (otherwise it's derived from the route name)
- `@tag` — Adds tags to group and organize your API operations
- `@throws` — Specify errors that could be thrown during the call
- Method descriptions are also captured in the OpenAPI document

This flexibility lets you define complex return types with complete accuracy. For example:

```
/**
 * @return Collection
 */
public function allUsers(User $user): Collection
{
    return User::all();
}

/**
 *
 * @return array{
 *     requestedAt: DateTime | null,
 *     users: User[],
 *     cars: Collection,
 *     carsWithPagination: LengthAwarePaginator,
 *     nestedObject: array{
 *         evenDeeper: array{
 *             message: string
 *         }
 *     }
 * }
 */
public function manything(Address $address): array
{
    return [];
}
```

### Here's what's happening:

[](#heres-whats-happening)

The package reads the docblocks and uses PHP's native type hints to generate detailed, nested TypeScript types and OpenAPI schemas.

Collections, paginated results, arrays with nested objects — everything gets parsed and converted correctly.

This means you can describe even very complex API responses in your controller methods and get fully typed clients on the frontend without any manual synchronization.

Specifying Request Parameters
-----------------------------

[](#specifying-request-parameters)

Your API request parameters can come from different places, and `laravel-type-generator` supports all of them to generate accurate types:

### 1. Route Path Parameters

[](#1-route-path-parameters)

Simply define parameters in your route URL, like `/users/{user}/`. These will be automatically detected and typed.

### 2. FormRequest Subclasses

[](#2-formrequest-subclasses)

You can define a FormRequest class with typed properties and validation rules. The package inspects both your docblock properties and validation rules to generate the parameter types.

Example:

```
/**
 * @property UploadedFile $file
 * @property string $nickname
 * @property array{
 *     name: string,
 *     age: int
 * } $person
 */
class GreetingRequest extends FormRequest
{
    public function rules(): array
    {
        return [
            'file' => ['file'],
        ];
    }
}
```

### 3. Docblock Annotations on Controller Methods

[](#3-docblock-annotations-on-controller-methods)

You can also specify request shapes directly in your controller method's docblocks using generics and param tags:

```
/**
 * Greet
 *
 * Generates a greeting message.
 *
 * @id greeting
 * @param Request $request
 * @param string $name The receiver's nickname.
 * @return Message|null The greeting message
 * @throws InvalidName Invalid name provided
 * @throws \InvalidArgumentException Invalid args provided
 */
public function greeting(Request $request, $name): ?Message
{
    // ...
}
```

This tells the package exactly what your request parameters should look like, allowing for precise type generation.

###  Health Score

38

—

LowBetter than 85% of packages

Maintenance77

Regular maintenance activity

Popularity15

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity43

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 75% 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

14

Last Release

269d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/57ee82f8ac85c20fb66ca3fed44b25ca936b99bc77d593ae117996252a9e609b?d=identicon)[martinpham](/maintainers/martinpham)

---

Top Contributors

[![MartinPham](https://avatars.githubusercontent.com/u/2064515?v=4)](https://github.com/MartinPham "MartinPham (3 commits)")[![onexer](https://avatars.githubusercontent.com/u/32367507?v=4)](https://github.com/onexer "onexer (1 commits)")

###  Code Quality

TestsPest

Code StylePHP CS Fixer

### Embed Badge

![Health badge](/badges/martinpham-laravel-type-generator/health.svg)

```
[![Health](https://phpackages.com/badges/martinpham-laravel-type-generator/health.svg)](https://phpackages.com/packages/martinpham-laravel-type-generator)
```

###  Alternatives

[anourvalar/eloquent-serialize

Laravel Query Builder (Eloquent) serialization

11320.2M21](/packages/anourvalar-eloquent-serialize)[statamic-rad-pack/runway

Eloquently manage your database models in Statamic.

135192.6k5](/packages/statamic-rad-pack-runway)

PHPackages © 2026

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