PHPackages                             kirschbaum-development/paragon - 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. [Utility &amp; Helpers](/categories/utility)
4. /
5. kirschbaum-development/paragon

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

kirschbaum-development/paragon
==============================

A Laravel package for generating enum-like objects in typescript based on PHP enum classes.

v1.2.0(10mo ago)816.1k↑11.5%MITPHPPHP ^8.1CI passing

Since Sep 23Pushed 10mo ago12 watchersCompare

[ Source](https://github.com/kirschbaum-development/paragon)[ Packagist](https://packagist.org/packages/kirschbaum-development/paragon)[ Docs](https://github.com/kirschbaum-development/paragon)[ RSS](/packages/kirschbaum-development-paragon/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (10)Dependencies (9)Versions (12)Used By (0)

Paragon
=======

[](#paragon)

[![Latest Version on Packagist](https://camo.githubusercontent.com/4fe47c5538fda8ad456f4a99258df19d9bd16a63643daba4ee5f43d4621d70f5/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6b69727363686261756d2d646576656c6f706d656e742f70617261676f6e2e737667)](https://packagist.org/packages/kirschbaum-development/paragon)[![Total Downloads](https://camo.githubusercontent.com/5ebd379c7ea512c37d482f29f2db2b6adae99edb1de4a6b828872d74cf0269da/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6b69727363686261756d2d646576656c6f706d656e742f70617261676f6e2e737667)](https://packagist.org/packages/kirschbaum-development/paragon)[![Actions Status](https://github.com/kirschbaum-development/paragon/actions/workflows/tests.yml/badge.svg)](https://github.com/kirschbaum-development/paragon/actions)

A tool for automatically generating typescript/javascript objects and utilities based on their PHP counterparts.

Table of Contents
-----------------

[](#table-of-contents)

- [Requirements](#requirements)
- [Installation](#installation)
- [Enums](#enums)
    - [Custom Enum Methods](#custom-enum-methods)
    - [Ignoring Enums or Methods](#ignoring-enums-or-public-methods)
    - [Configuration](#configuration)
    - [Recommendations](#recommendations)
    - [Automatically Regenerate](#automatically-re-generating-when-modifying-php-enums)
    - [Technical Details](#technical-details-)
- [Events](#broadcast-events)
    - [Usage](#usage)

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

[](#requirements)

Laravel VersionParagon Version12.0^1.011.0^1.010.0^1.0Installation
------------

[](#installation)

```
composer require kirschbaum-development/paragon
```

Enums
-----

[](#enums)

**TL;DR:** Run the following command to generate Typescript (or Javascript) enums from your PHP enums:

```
php artisan paragon:enum:generate
```

That's it. Now, wherever you may have had enums in your project, "paragons" or near perfect duplicates of those have been recreated inside of `resources/js/enums`. Here are some examples of the API:

```
use App\Enums\Status;

Status::Active;
Status::Active->value;
Status::cases();
Status::from('active');
Status::tryFrom('active');
```

```
import Status from '@/js/enums/Status.ts';

Status.Active;
Status.Active.value;
Status.cases();
Status.from('active');
Status.tryFrom('active');
```

As you can see the API is nearly the same, the only difference being how the two languages expect you to access objects!

**Generating javascript enums**

This package also supports generating Javascript enums. To do so, simply pass the `--javascript` flag to the command:

```
php artisan paragon:enum:generate --javascript
```

#### Public Methods

[](#public-methods)

A good majority of the time it is useful to use public methods to return a proper human-readable label or some other functionality on an enum. Paragon got this covered too. Assuming the following method exists on the above `Status` enum:

```
public function label(): string
{
    return match ($this) {
        self::Active => 'Active',
        self::Inactive => 'Inactive',
    };
}

public function color(): string
{
    return match ($this) {
        self::Active => 'bg-green-100',
        self::Inactive => 'bg-red-100',
    };
}
```

The following method would become accessible using TypeScript:

```
Status.Active.label() // 'Active'
Status.Inactive.label() // 'Inactive'
Status.Active.color() // 'bg-green-100'
Status.Inactive.color() // 'bg-red-100'
```

### Custom Enum Methods

[](#custom-enum-methods)

While this package ignores static methods on the PHP Enums, we allow you to create additional methods that Paragon will make available for every generated Enum.

```
php artisan paragon:enum:add-method
```

You will be prompted to search for the enum this method should belong to. It will be placed inside a directory that matches the namespace of the enum. For example, an enum at `App\Enums\Status` would place an enum method file at `resources/js/vendors/paragon/enums/App/Enums/Status`. You are free to do whatever you need inside this file. You have direct access to `this.items` which allows you to interact with the enum cases in whatever way you need. Just keep in mind that because the items are "frozen", you can't mutate them directly. An example would be to have a method that automatically generates a select list from your Enum.

If you need to create a method that is available to every enum, just create an enum method with the `--global` or `-g` flag.

```
php artisan paragon:enum-method --global
```

This will create a new file at `resources/js/vendors/paragon/enums` containing a method.

### Ignoring Enums Or Public Methods

[](#ignoring-enums-or-public-methods)

There may be enums or enum methods that you don't want inside your automatically generated code. If this is the case simply use the `IgnoreParagon` attribute.

```
use Kirschbaum\Paragon\Concerns\IgnoreParagon;

#[IgnoreParagon]
enum IgnoreMe
{
    case Ignored;
}
```

```
use Kirschbaum\Paragon\Concerns\IgnoreParagon;

enum Status
{
    // ...

    #[IgnoreParagon]
    public method ignoreMe()
    {
        // ...
    }
}
```

### Configuration

[](#configuration)

You can publish the configuration file by running `php artisan vendor:publish` and locating the Paragon config which will be published at `config/paragon.php`.

### Recommendations

[](#recommendations)

It is recommended that the generated path for the enums is added to the `.gitignore` file. Make sure to run this command during deployment if you do this.

### Automatically Re-generating When Modifying PHP Enums

[](#automatically-re-generating-when-modifying-php-enums)

Install the [`vite-plugin-watch`](https://www.npmjs.com/package/vite-plugin-watch) plugin in your project via `npm`:

```
npm i -D vite-plugin-watch
```

In your `vite.config.js` file, import the plugin, and add the plugin paramaters to your plugins array:

```
import { watch } from "vite-plugin-watch";

export default defineConfig({
    plugins: [
        // ...

        watch({
            pattern: "app/Enums/**/*.php",
            command: "php artisan paragon:generate-enums",
        }),
    ],
});
```

### Technical Details 🤓

[](#technical-details-)

Enums are a fantastic addition to the PHP-verse but are really lame in the TypeScript-verse. However, it can be annoying trying to get those enum values on the front-end of your project. Are you supposed to pass them as a method when returning a view or perhaps via an API? This generator solves that problem by scraping your app directory for any and all enums and recreates them as TypeScript classes so you can import them directly into your Vue, React, or Svelte front-end!

Let's take a closer look at a simple PHP enum and its generated Typescript code.

```
namespace App\Enums;

enum Status: string
{
    case Active = 'active';
    case Inactive = 'inactive';
}
```

```
import Enum from '../Enum.ts';

type StatusDefinition = {
    name: string;
    value: string;
};

class Status extends Enum {
    protected static items = Object.freeze({
        Active: Object.freeze({
            name: 'Active',
            value: 'active',
        }),
        Inactive: Object.freeze({
            name: 'Inactive',
            value: 'inactive',
        }),
    });

    public static get Active(): AlarmStatusDefinition {
        return this.items['Active'];
    }

    public static get Inactive(): AlarmStatusDefinition {
        return this.items['Inactive'];
    }
}

export default Status;
```

At first glance it appears as though a lot more stuff is happening, but the above generated code allows us to interact with the enum in a nearly identical way as in PHP. And you may notice the generated TypeScript class extends the `Enum`class. This gives us some underlying functionality that is available to every enum.

Broadcast Events
----------------

[](#broadcast-events)

**TL;DR:** Run the following command to generate a Typescript (or Javascript) broadcast event object based on your broadcastable events:

```
php artisan paragon:event:generate
```

Any events within the `App\Events` namespace will be automatically added to the `Events` object. Just make sure your event implements the `ShouldBroadcast` contract!

If javascript is needed, just make sure to add the `--javascript` or `-j` flag.

### Usage

[](#usage)

The primary usage of this tool is for Laravel Echo. Listening to for an event class based on a hard-coded string is not exactly preferable. The can easily get out of sync or just get mistyped.

Here is a quick example event:

```
namespace App\Events;

class ParagonGenerated implements ShouldBroadcast
{
    // ...
}
```

Then listen for it with Echo:

```
import Events from '@/events/Events.ts';

Echo.channel(...)
    .listen(Events.ParagonGenerated, /* ... */);
```

If you have defined a `broadcastOn` method that returns a custom name, this will be handled correctly for you as well.

One thing to note is that if an event namespace starts with `App\Events` or `App`, these will be removed from the dot path within the object. If an event is nested, the dot path will reflect this: For example:

```
namespace App\Support;

class NestedEvent implements ShouldBroadcast
{
    // ...
}
```

```
import Events from '@/events/Events.ts';

Echo.channel(...)
    .listen(Events.Support.NestedEvent, /* ... */);
```

###  Health Score

42

—

FairBetter than 90% of packages

Maintenance54

Moderate activity, may be stable

Popularity31

Limited adoption so far

Community15

Small or concentrated contributor base

Maturity55

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 78.6% 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 ~31 days

Recently: every ~63 days

Total

10

Last Release

321d ago

Major Versions

v0.1.3 → v1.0.02024-10-21

PHP version history (2 changes)v0.1.0PHP ^8.0

v0.1.1PHP ^8.1

### Community

Maintainers

![](https://www.gravatar.com/avatar/5f56743d64d77958321d43b2df49e9696d19c9dd99995730c5c38ccae50408fa?d=identicon)[Kirschbaum](/maintainers/Kirschbaum)

---

Top Contributors

[![brandonferens](https://avatars.githubusercontent.com/u/1819546?v=4)](https://github.com/brandonferens "brandonferens (44 commits)")[![luisdalmolin](https://avatars.githubusercontent.com/u/403446?v=4)](https://github.com/luisdalmolin "luisdalmolin (7 commits)")[![dwjordan](https://avatars.githubusercontent.com/u/22681503?v=4)](https://github.com/dwjordan "dwjordan (4 commits)")[![michaelfox](https://avatars.githubusercontent.com/u/37444?v=4)](https://github.com/michaelfox "michaelfox (1 commits)")

---

Tags

laraveleventsactions

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/kirschbaum-development-paragon/health.svg)

```
[![Health](https://phpackages.com/badges/kirschbaum-development-paragon/health.svg)](https://phpackages.com/packages/kirschbaum-development-paragon)
```

###  Alternatives

[barryvdh/laravel-ide-helper

Laravel IDE Helper, generates correct PHPDocs for all Facade classes, to improve auto-completion.

14.9k123.0M687](/packages/barryvdh-laravel-ide-helper)[yajra/laravel-datatables-oracle

jQuery DataTables API for Laravel

4.9k33.8M339](/packages/yajra-laravel-datatables-oracle)[tormjens/eventy

The WordPress filter/action system in Laravel

438912.9k16](/packages/tormjens-eventy)[genealabs/laravel-changelog

A Laravel Nova tool.

55250.7k](/packages/genealabs-laravel-changelog)[erlandmuchasaj/laravel-gzip

Gzip your responses.

40129.3k2](/packages/erlandmuchasaj-laravel-gzip)[tehwave/laravel-achievements

Simple, elegant Achievements the Laravel way

7012.8k](/packages/tehwave-laravel-achievements)

PHPackages © 2026

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