Vite plugin for Laravel Enumify — automatically sync PHP enums to TypeScript during development and builds.
php artisan enumify:sync --force --quiet before Vite compilesconfig/enumify.php to discover paths and watch confignpm install @devwizard/vite-plugin-enumify --save-dev
# or
pnpm add -D @devwizard/vite-plugin-enumify
# or
yarn add -D @devwizard/vite-plugin-enumify
This plugin is package-manager agnostic and works with npm, pnpm, or yarn. The runtime behavior is identical regardless of how you install it.
Add the plugin to your vite.config.ts:
import { defineConfig } from "vite";
import laravel from "laravel-vite-plugin";
import enumify from "@devwizard/vite-plugin-enumify";
export default defineConfig({
plugins: [
enumify(),
laravel({
input: ["resources/js/app.ts"],
refresh: true,
}),
],
});
php artisan enumify:sync --force --quiet before Vite compiles TypeScript.config/enumify.php and re-syncs on changes.enumify({
// PHP binary path (default: "php")
artisanBin: "php",
// Path to the artisan file (default: "artisan")
artisanFile: "artisan",
// Command to run (default: "enumify:sync")
syncCommand: "enumify:sync",
// Working directory (default: process.cwd())
cwd: process.cwd(),
// Enable watch mode in development (default: runtime.watch from config/enumify.php)
watch: true,
// Additional environment variables
env: {},
});
The plugin reads config/enumify.php to discover enum paths and output paths so it can watch the right files and avoid feedback loops.
Given this PHP enum:
// app/Enums/OrderStatus.php
enum OrderStatus: string
{
case PENDING = 'pending';
case PROCESSING = 'processing';
case SHIPPED = 'shipped';
public function label(): string
{
return match ($this) {
self::PENDING => 'Pending',
self::PROCESSING => 'Processing',
self::SHIPPED => 'Shipped',
};
}
public function color(): string
{
return match ($this) {
self::PENDING => 'yellow',
self::PROCESSING => 'blue',
self::SHIPPED => 'green',
};
}
}
The plugin generates:
// resources/js/enums/order-status.ts
export const OrderStatus = {
PENDING: "pending",
PROCESSING: "processing",
SHIPPED: "shipped",
} as const;
export type OrderStatus = (typeof OrderStatus)[keyof typeof OrderStatus];
export const OrderStatusUtils = {
label(status: OrderStatus): string {
switch (status) {
case OrderStatus.PENDING:
return "Pending";
case OrderStatus.PROCESSING:
return "Processing";
case OrderStatus.SHIPPED:
return "Shipped";
}
},
color(status: OrderStatus): string {
switch (status) {
case OrderStatus.PENDING:
return "yellow";
case OrderStatus.PROCESSING:
return "blue";
case OrderStatus.SHIPPED:
return "green";
}
},
options(): OrderStatus[] {
return Object.values(OrderStatus);
},
};
mainnpm run build and npm run typecheckRelease tip: tag releases after merging to main, then publish to NPM.
MIT