PHPackages                             genericmilk/cooker - 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. genericmilk/cooker

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

genericmilk/cooker
==================

The Laravel-native frontend toolkit. Tailwind, React, Vue, TS — without the Node baggage.

10.0.0(2mo ago)66.7kMITPHPPHP &gt;=8.3CI passing

Since Oct 10Pushed 2mo ago1 watchersCompare

[ Source](https://github.com/genericmilk/cooker)[ Packagist](https://packagist.org/packages/genericmilk/cooker)[ RSS](/packages/genericmilk-cooker/feed)WikiDiscussions master Synced yesterday

READMEChangelog (4)Dependencies (17)Versions (44)Used By (0)

 [![](banner.png)](banner.png)

Cooker is the Laravel-native frontend toolkit. It gives you Tailwind, React, Vue, TypeScript and JSX/TSX bundling — all driven from `php artisan`, with no Node, no `npm`, no `node_modules` and no `package-lock.json` in your project.

Cooker auto-downloads the binaries it needs (`esbuild`, `tailwindcss`) into `.cooker/bin`. npm packages are fetched directly from the registry and stored flat in `.cooker/packages`. Built assets are written to `public/build` as static files with hashed names.

---

Table of contents
-----------------

[](#table-of-contents)

- [Why Cooker?](#why-cooker)
- [Requirements](#requirements)
- [Installation](#installation)
- [Concepts](#concepts)
- [Adding a stack](#adding-a-stack)
- [Adding npm packages](#adding-npm-packages)
- [The `@cooker` directive](#the-cooker-directive)
- [Building &amp; watching](#building--watching)
- [Configuration](#configuration)
- [Upgrading from Cooker 8](#upgrading-from-cooker-8)

---

Why Cooker?
-----------

[](#why-cooker)

If you've worked with Laravel + Vite or Laravel Mix you'll be familiar with the Node-shaped hole in your project: a `package.json`, a giant `node_modules`, a lockfile, and a separate dev server. Cooker replaces all of that with one Composer package and a small workspace folder.

- **No Node required.** Cooker drives `esbuild` and `tailwindcss` as standalone binaries.
- **No `node_modules`.** Packages live flat at `.cooker/packages//`. Cooker resolves transitive deps for you.
- **One command to install a stack.** `php artisan cooker:add react` installs React + ReactDOM and scaffolds a working `App.jsx`.
- **Beginner-friendly defaults.** `@cooker('app.js')` and `@cooker('app.css')` Just Work.
- **Static assets in production.** No PHP runtime asset routes — `public/build/*.js` is served by your web server like any other static file.

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

[](#requirements)

- PHP **&gt;= 8.3**
- Laravel 10 or newer
- ext-zlib, ext-phar, ext-json (standard with most PHP builds)

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

[](#installation)

```
composer require genericmilk/cooker
php artisan cooker:install
```

The installer will:

1. Publish `config/cooker.php`.
2. Create `.cooker/` (bin, cache, packages) and add it to `.gitignore`.
3. Scaffold starter recipes at `resources/js/app.js` and `resources/css/app.css`.
4. Download `esbuild` for your platform.
5. Optionally bootstrap a stack (`react`, `vue`, `tailwind`).

After install, drop into a Blade view:

```

    @cooker('app.css')

    @cooker('app.js')

```

Then build:

```
php artisan cooker:cook        # production build
php artisan cooker:watch       # dev — rebuilds on save
```

Concepts
--------

[](#concepts)

### Recipes

[](#recipes)

A **recipe** maps an output filename to a single entry file. Configured in `config/cooker.php`:

```
'recipes' => [
    'app.js'  => 'resources/js/app.js',
    'app.css' => 'resources/css/app.css',
],
```

The output filename's extension determines the loader (`.js`/`.mjs` → script, `.css` → stylesheet). The entry's extension determines parsing — Cooker handles `.js`, `.ts`, `.jsx`, `.tsx`, `.mjs`, `.css`, `.less`, and `.scss`.

You import other files normally inside the entry — Cooker bundles them with esbuild.

### The `.cooker/` workspace

[](#the-cooker-workspace)

```
.cooker/
├── bin/              ← auto-downloaded binaries (esbuild, tailwindcss)
├── cache/            ← intermediate compiled CSS, etc.
├── packages/         ← flat npm package extracts
└── cooker.json       ← installed packages + active stacks

```

`.cooker/cooker.json` is your project's manifest — it's the only file inside `.cooker/` that's checked into git.

Adding a stack
--------------

[](#adding-a-stack)

Stacks are opinionated bundles — they install the right packages, scaffold a working starter, and wire everything in.

```
php artisan cooker:add react        # React 18 + scaffolded App.jsx
php artisan cooker:add vue          # Vue 3 + scaffolded App.js
php artisan cooker:add tailwind     # Tailwind 4 — adds @import "tailwindcss"
```

After `cooker:add react`:

```
resources/js/
├── app.jsx                  ← entry; mounts  to #app
└── components/App.jsx       ← starter component

```

Update `config/cooker.php` to point the recipe at `app.jsx`:

```
'recipes' => [
    'app.js' => 'resources/js/app.jsx',
],
```

Adding npm packages
-------------------

[](#adding-npm-packages)

```
php artisan cooker:add lodash
php artisan cooker:add @floating-ui/dom@^1
php artisan cooker:add zod@latest
```

Cooker fetches the tarball straight from the npm registry, extracts it to `.cooker/packages//` and resolves transitive dependencies. There's no `package.json` and no lockfile — `cooker.json` records the top-level packages you asked for.

In your code:

```
import _ from 'lodash';
import { z } from 'zod';
```

Remove with:

```
php artisan cooker:remove lodash
```

The `@cooker` directive
-----------------------

[](#the-cooker-directive)

```
@cooker('app.css')
@cooker('app.js')
```

Reads `public/build/manifest.json` and emits the right tag with the hashed filename:

```

```

If a build hasn't been produced for the recipe yet, Cooker emits an HTML comment telling you to run `cooker:cook`.

Building &amp; watching
-----------------------

[](#building--watching)

```
php artisan cooker:cook                    # production build, minified
php artisan cooker:cook --no-minify        # disable minification
php artisan cooker:cook --sourcemap        # emit sourcemaps
php artisan cooker:cook --clean            # wipe public/build first
php artisan cooker:watch                   # dev — incremental rebuilds on file change
php artisan cooker:watch --no-hmr          # disable live reload
```

In `app.debug=true` environments, `cooker:cook` defaults to non-minified + sourcemaps. In production, it minifies and skips sourcemaps. Override per-environment with `COOKER_MINIFY` and `COOKER_SOURCEMAP` env vars.

Live reload
-----------

[](#live-reload)

`cooker:watch` runs an embedded SSE server (default `127.0.0.1:5173`) and the `@cooker` directive injects a tiny client snippet into your pages — but **only when `APP_DEBUG=true`**.

- **CSS-only changes** hot-swap the matching `` tag, no full reload.
- **JS or mixed changes** trigger `location.reload()`.
- The client auto-reconnects if the watcher restarts.

Configure host/port in `config/cooker.php` under `dev`, or via `COOKER_DEV_HOST` / `COOKER_DEV_PORT`. Disable entirely with `COOKER_DEV_ENABLED=false` or `--no-hmr`.

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

[](#configuration)

`config/cooker.php` is short on purpose:

```
return [
    'recipes' => [
        'app.js'  => 'resources/js/app.js',
        'app.css' => 'resources/css/app.css',
    ],
    'output' => [
        'path' => 'public/build',
        'url'  => '/build',
    ],
    'toolbox' => [
        'path'     => '.cooker/bin',
        'esbuild'  => '0.24.2',
        'tailwind' => '4.0.0',
    ],
    'packages' => [
        'path'     => '.cooker/packages',
        'manifest' => '.cooker/cooker.json',
        'registry' => env('COOKER_REGISTRY', 'https://registry.npmjs.org'),
    ],
    'build' => [
        'minify'    => env('COOKER_MINIFY', null),
        'sourcemap' => env('COOKER_SOURCEMAP', null),
        'target'    => env('COOKER_TARGET', 'es2020'),
    ],
];
```

Upgrading from Cooker 8
-----------------------

[](#upgrading-from-cooker-8)

Cooker 10 is a clean rewrite. The runtime PHP asset server (`__cooker/{file}`), `Ovens`, `Preparsers` and the `import name from 'name'` rewrite-to-CDN behaviour are all gone. To upgrade:

1. `composer require genericmilk/cooker:^10`
2. `php artisan cooker:uninstall` (in your old project) or delete `config/cooker.php` and `.cooker/` manually.
3. `php artisan cooker:install`.
4. Move your hand-written code into the new `resources/js/app.js` / `resources/css/app.css` entry files and add real `import` statements.
5. Replace any old `cooker-toolbelt` / `cooker-routes` imports — they're not part of Cooker 10.
6. For each npm package you used to import directly from `esm.run`, run `php artisan cooker:add `.

License
-------

[](#license)

MIT — see [LICENSE](LICENSE).

###  Health Score

57

—

FairBetter than 98% of packages

Maintenance87

Actively maintained with recent releases

Popularity27

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity86

Battle-tested with a long release history

 Bus Factor1

Top contributor holds 98.7% 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 ~64 days

Recently: every ~187 days

Total

38

Last Release

65d ago

Major Versions

4.1.5 → 5.0.02022-08-03

5.0.0 → 6.0.02023-03-22

6.0.5 → 7.0.02024-02-24

7.0.5 → 8.0.02025-01-06

8.1.0 → 10.0.02026-04-29

PHP version history (7 changes)v1.0PHP &gt;=7.0

3.0.2PHP &gt;=7.3

4.1.0PHP &gt;=7.4

4.1.3PHP &gt;=8.0

6.0.0PHP &gt;=8.2

6.0.2PHP &gt;=8.1

8.0.0PHP &gt;=8.3

### Community

Maintainers

![](https://www.gravatar.com/avatar/3cff61292b60883c06681d13acfaf0942d1cdbb9313a1a111a9f61f9618d9f60?d=identicon)[genericmilk](/maintainers/genericmilk)

---

Top Contributors

[![genericmilk](https://avatars.githubusercontent.com/u/1846127?v=4)](https://github.com/genericmilk "genericmilk (306 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (4 commits)")

---

Tags

laraveltailwindreactfrontendvuebundleresbuildcooker

###  Code Quality

TestsPest

### Embed Badge

![Health badge](/badges/genericmilk-cooker/health.svg)

```
[![Health](https://phpackages.com/badges/genericmilk-cooker/health.svg)](https://phpackages.com/packages/genericmilk-cooker)
```

###  Alternatives

[laravel/framework

The Laravel Framework.

34.8k543.8M20.1k](/packages/laravel-framework)[statamic/cms

The Statamic CMS Core Package

4.8k3.6M985](/packages/statamic-cms)[laravel/boost

Laravel Boost accelerates AI-assisted development by providing the essential context and structure that AI needs to generate high-quality, Laravel-specific code.

3.5k21.5M587](/packages/laravel-boost)[nativephp/mobile

NativePHP for Mobile

1.1k75.1k91](/packages/nativephp-mobile)[drupal/core

Drupal is an open source content management platform powering millions of websites and applications.

21866.0M1.7k](/packages/drupal-core)[roots/acorn

Framework for Roots WordPress projects built with Laravel components.

9762.4M131](/packages/roots-acorn)

PHPackages © 2026

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