Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Typescript Laravel Package

based/laravel-typescript

based/laravel-typescript generates TypeScript definitions from Laravel models, resources, and routes, keeping frontend and backend types in sync via artisan commands and configurable output.

View on GitHub
Deep Wiki
Context7

Getting Started

based/laravel-typescript is a small code-generation utility: it reflects on your Eloquent models and emits TypeScript interfaces so your frontend can share the backend's shape instead of duplicating it by hand.

Minimal setup:

composer require based/laravel-typescript
php artisan vendor:publish --tag=typescript   # confirm the tag/provider from the publish list

Then open the published config/typescript.php. This is the first file to read — it controls the output directory (typically something like resources/js/types) and which models are transformed. Register a model, run the transform command, and inspect the generated file:

php artisan typescript:transform

The fastest first use case is a single User model consumed by an Inertia or API-backed page:

import type { User } from '@/types'

Once that import type-checks, expand registration model by model rather than pointing the package at your entire app/Models directory. Where to look next: the package's src/ transformers to understand how casts and relations are interpreted, and the generated output itself to see what was inferred versus omitted.

Implementation Patterns

Treat generated interfaces as build artifacts. Decide up front whether the output directory is committed or generated during npm run dev / CI. Committing gives reviewers a visible schema diff; generating avoids merge conflicts. Either way, never hand-edit generated files.

Wire generation into the frontend build. A typical package.json:

"scripts": {
  "types": "php artisan typescript:transform",
  "dev": "npm run types && vite"
}

For CI, regenerate and fail on drift:

- run: php artisan typescript:transform
- run: git diff --exit-code resources/js/types

Let casts drive the types. The quality of the output depends on how explicit your models are. Set $casts for dates, decimals, JSON, and enums; the transformer has much less to infer otherwise. If a column is nullable or an accessor can return null, make that explicit in the model or correct it in a wrapper type.

Layer hand-written types on top. Generated interfaces describe persistence, not page props or API envelopes. Keep a small types/app.ts that composes them:

import type { User } from './generated'

export type UserForm = Pick<User, 'name' | 'email'>
export type Paginated<T> = { data: T[]; links: Record<string, string> }

Handle relations deliberately. Nested interfaces are useful but circular relations (User → Post → User) are a common source of broken or recursive output. Prefer generating flat interfaces and composing relations in hand-written types, or break cycles at the transformer/config level.

Use literal unions for enums and statuses. If your model casts to a PHP enum, make sure the frontend gets a union ('draft' | 'published') rather than string. If the package version doesn't emit that automatically, maintain a small mapping and reference it from your wrapper types.

Type Inertia props and API resources from the same interfaces. The main day-to-day payoff is that a controller change that alters a model's shape produces a TypeScript error at the component or client call site — provided the generation step runs before type-checking.

Gotchas and Tips

  • Maturity is the biggest gotcha. Last release was July 2021, with a small dependent base. Expect friction on Laravel 9+/PHP 8.1+ (deprecations, signature changes). Pin the version, and be prepared to fork or vendor the transformer if you need it long-term.
  • Confirm the actual API surface against the README for your installed version. Command names, config keys, and whether models are registered via config or a contract/trait have shifted across the 1.x line; don't assume the examples in blog posts match.
  • Reflection is not omniscience. Hidden attributes, $appends accessors, computed properties, and custom Attribute casts often won't appear or will appear with the wrong type. Generated interfaces reflect what the package can see, not what your API actually returns.
  • Database schema may be consulted. If the transformer introspects columns, the command needs a working DB connection and up-to-date migrations — running it in a fresh CI job without a database will fail or silently produce empty interfaces.
  • Nullability is a frequent mismatch. A nullable column mapped to string instead of string | null will pass TypeScript but fail at runtime. Audit generated output for null-able fields after the first run.
  • Dates are strings on the wire. Laravel serializes dates to ISO strings by default; if the generated type says otherwise, correct it in your wrapper layer rather than fighting the generator.
  • Duplicate model basenames collide. App\Models\User and Admin\Models\User both want to emit User. Namespace or rename via config before this becomes a debugging session.
  • Overwrites are silent. Re-running the command replaces files. Any manual fix you made will disappear; keep fixes in separate, non-generated files.
  • Debugging output means reading the transformer. When a field is missing or mistyped, trace it from the model's $casts and relation methods through the transformer source. There's no verbose mode to rely on.
  • Extension points are limited but real. The config output path, model registration, and the transformer classes themselves are the places to customize. For anything substantial — custom casts, enum handling, cycles — a small fork is usually cleaner than fighting the package's assumptions.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource