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

Ts Bundle Laravel Package

yabx/ts-bundle

yabx/ts-bundle is a PHP package for bundling and managing TypeScript assets in your application. It streamlines TypeScript build integration with straightforward configuration, helping keep frontend assets organized, maintainable, and easier to manage within your development workflow.

View on GitHub
Deep Wiki
Context7

Getting Started

Reality check first. yabx/ts-bundle is a Symfony bundle (targeting Symfony 8) with effectively zero ecosystem adoption (2 stars, 0 dependents). It is not a Laravel package. Before you invest any time, confirm what it actually does in your context: it is a TypeScript mapper — it walks PHP class metadata and emits .d.ts/interface definitions so your front end and back end stay in sync. For a Laravel developer, that is still a genuinely useful idea — you just won't get Laravel-native wiring out of the box.

Minimal steps:

  1. Install and inspect, don't wire yet.

    composer require yabx/ts-bundle
    

    Then read vendor/yabx/ts-bundle/ — specifically src/ for the mapper/service classes, any DependencyInjection/ extension, and any console command registered. This tells you whether there's a standalone entry point you can call from Laravel, or whether everything is bound to Symfony's container.

  2. Find the generation command. Most bundles of this shape register a bin/console command (something like ts:generate/ts:dump). If one exists, the fastest first use case is: run it once against a single class and see what it emits.

    php artisan list | grep -i ts   # it almost certainly won't appear
    php vendor/bin/...              # check for a standalone binary
    
  3. Start with one DTO, not your whole model layer. Define a plain PHP class with typed properties:

    final readonly class UserSummary
    {
        public function __construct(
            public int $id,
            public string $name,
            public ?string $avatarUrl,
            public \DateTimeImmutable $createdAt,
        ) {}
    }
    

    Feed it to the mapper and inspect the output. That single sample tells you how it handles nullables, DateTimeInterface, and constructor promotion — the three things that most often produce wrong TypeScript.

  4. If the Symfony coupling is too tight, don't fight it. Pull the mapper class in isolation (instantiate it directly, bypass the bundle), or use it as a reference implementation and write a 100-line generator around nikic/php-parser or Laravel's ReflectionClass. For a package this small, forking a single service is often cheaper than adapting the bundle.

Where to look first: the mapper service itself (how it resolves property types), the config schema, and the console command. Those three files are the whole package.

Implementation Patterns

DTO-first, not Eloquent-first. The mapper needs clean, typed class metadata. Eloquent models are dynamic magic — $fillable, casts, accessors, relations resolved at runtime — and this bundle has no Eloquent driver. The reliable pattern is to introduce explicit DTOs/Resources that mirror your API responses, map to TypeScript from those, and let your Eloquent models stay out of the contract entirely.

// App\Data\UserResource  -> generates `UserResource` TS interface
final readonly class UserResource
{
    public function __construct(
        public int $id,
        public string $email,
        public ?string $phone,
        public UserStatus $status,     // backed enum -> string union
        public CarbonImmutable $joinedAt,
    ) {}
}

Pipeline placement. Generate types as a build step, not a runtime concern:

// package.json
"scripts": {
  "types:generate": "php artisan ts:generate",
  "dev": "npm run types:generate && vite",
  "build": "npm run types:generate && vite build"
}

CI drift guard. The single highest-value pattern with any type generator: in CI, regenerate and fail if the working tree changes. This catches the case where someone edits a DTO and forgets to re-emit types — the whole class of bugs that makes synced types worth having.

- run: php artisan ts:generate
- run: git diff --exit-code resources/js/types/ || (echo "TS types out of date" && exit 1)

Where to put output. Commit generated types to a single directory (resources/js/types/) and never hand-edit them. Add a header banner if the mapper supports templates; if not, a post-generation sed is fine.

Enum mapping. Backed string enums map cleanly to TS string unions or enums. Use them aggressively — they're the mapping that survives refactors best and gives you the most value per line.

Versioning the contract. Treat the generated file as part of your API surface. If you have a public API, tag or snapshot the emitted types alongside releases so downstream consumers can diff.

Front-end consumption. Import the generated interfaces into your Inertia props / fetch layer and let TypeScript enforce the shape at every call site. This is the payoff: rename a DTO property and tsc lights up every consumer.

Gotchas and Tips

  • Symfony 8 constraint. Check composer.json's symfony/* requirement. If it pins Symfony 8 components, it may pull in packages that conflict with Laravel's existing Symfony version constraints. Resolve this before committing — do not let a type generator reshape your whole dependency tree.
  • No Eloquent metadata. Do not expect it to introspect models, migrations, or casts(). Feed it DTOs. If you want model-derived types, write a small exporter that converts your models to DTOs first.
  • DateTimeInterface handling. This is the most common source of wrong types. Most mappers emit string, which is correct over JSON, not Date. Verify what yours does; a mismatch here silently produces type-unsound code that compiles fine.
  • Nullable vs optional. ?string $foo means string | null (always present, possibly null), not foo?: string. If the mapper conflates them — or if your API omits null fields — your front-end null checks will be wrong. Check emitted output for ?: vs | null.
  • Circular references. Bidirectional relations in object graphs will either blow up, emit infinite recursion, or produce broken interface references. Keep DTOs flat or ensure the mapper deduplicates by FQCN.
  • Union/intersection types and generics. PHP type hints map imperfectly. array becomes any[] or unknown[] — you lose value shape. Nested generics (Collection<int, UserResource>) frequently degrade. Annotate DTOs with docblocks and check whether the mapper reads @var/@param.
  • Config quirks. Bundle config is loaded via Symfony's Extension; in Laravel you won't have config/packages/*.yaml. Options like output path, namespace, and type overrides likely need to be passed programmatically to the service constructor. Read the Configuration class to find the actual keys — don't guess.
  • Debugging wrong output. Work backwards from a minimal single-property class. Add properties one at a time; the first property whose emitted type surprises you is your culprit (usually a nullable, an enum, or a DateTime).
  • Extension points. Look for interfaces the bundle allows you to implement — a type transformer/mapper contract is common and is where you'd register custom handling for value objects, enums, or CarbonImmutable. If none exists, subclassing or forking is the path.
  • Bus factor. 2 stars, 0 dependents, one maintainer. Pin to an exact version ("yabx/ts-bundle": "1.0.x" or whatever the real tag is), vendor or fork it if it becomes load-bearing, and budget a day to replace it with an in-house generator if it breaks. Given the small surface area, an in-house ReflectionClass-based generator is a realistic fallback and removes the Symfony dependency entirely.
  • Laravel-native alternatives to weigh. Before adopting, compare against simply hand-writing a few interfaces, or using a Laravel-shaped generator. For most projects under ~50 DTOs, a hand-rolled Artisan command using ReflectionClass gives you 80% of the value with 0% of the dependency risk.
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.
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package