Looking to hire Laravel developers? Try LaraJobs
This package is not available.

laravel-goat maintained by meehh

Description
Terminal-first Laravel feature generator — template & boilerplate for full feature slices (Model, Requests, Resources, Service, Repository, Policy, Tests) from a single migration or ERD. Not just CRUD.
Last update
2026/09/05 06:20 (dev-main)
License
Downloads
0

Comments
comments powered by Disqus

🐐 GOAT

Terminal-first Laravel Feature Generator

Template · Boilerplate · Feature Slice — from a single migration or ERD

🐐 Your schema is already there. Why build around it manually when the structure you've already defined could be the starting point for everything that comes next?

PHP ^8.3 Laravel 11|12|13 Tests 40/40 License MIT Local First Version v1.0.0 Owner Prof Alex / TE-AD

php artisan goat:make Product

Why GOAT?

You paste a schema. GOAT ships the whole slice — not just a controller.

You give

Schema::create('products', function($t){
  $t->id();
  $t->foreignId('category_id')->constrained();
  $t->string('name');
  $t->decimal('price',10,2);
  $t->timestamps();
});

or a plain ERD:

products
---------
id bigint PK
name varchar
price decimal(10,2)

You get — template-ready

Product
├── 📄 2024_*_create_products_table.php
├── 🧩 Product.php (fillable, casts, belongsTo)
├── ✅ StoreProductRequest.php
├── ✅ UpdateProductRequest.php
├── 🔌 ProductResource.php
├── 🎮 ProductController.php (thin)
├── 🧠 ProductService.php (business)
├── 🗄️ ProductRepository.php (query)
├── 🔒 ProductPolicy.php
└── 🧪 ProductTest.php

Service → Repository, Resource, Policy, Tests included.

No AI. No SaaS. No web UI. Pure PHP — runs 100% locally.


✨ Feature Generator, not just CRUD

CRUD generator GOAT — Feature / Template / Boilerplate
Model + Controller + Service + Repository (separation)
No validation + Store/Update Requests with inferred rules
No API layer + JsonResource
No auth + Policy (7 methods)
No tests + Feature tests (5 scenarios)
One table = one file ERD with N tables → N slices
Hardcoded paths All paths & namespaces configurable
Fixed stubs Publish & customize — vendor:publish --tag=goat-stubs

Use it as:

  • CRUD scaffold for admin panels
  • Feature slice for clean architecture (Service/Repo)
  • Boilerplate / template for new domains (Inventory, Order, Booking)
  • Rapid prototyping from an ERD whiteboard

⚡ 10 seconds to first feature

composer require meehh/laravel-goat --dev
php artisan goat:make Product
🐐 GOAT — Laravel Feature Generator

How do you want to define Product?
❯ Paste Migration
  Paste ERD
  Use Existing Migration

Paste your migration. Press Ctrl+D when finished:
> Schema::create('products', ...);
> ^D

✓ Schema detected
 Product (products)
 ├── id bigInteger (PK)
 ├── category_id foreignId → categories.id
 ├── name string
 ├── price decimal
 └── created_at timestamp

Generate:
 ✓ Model  ✓ Migration  ✓ Requests  ✓ Resource  ✓ Controller  ✓ Service  ✓ Repository  ✓ Policy  ✓ Tests

✓ app/Models/Product.php
✓ app/Services/ProductService.php
...
🐐 GOAT generated Product successfully!
cat migration.php | php artisan goat:make Product --from=migration --force
cat erd.txt | php artisan goat:make Product --from=erd --force
php artisan goat:make Product --from=database/migrations/2024_01_01_create_products_table.php
php artisan goat:make Product --only=model,resource,request
php artisan goat:make Product --except=policy,test
# custom paths — e.g. repo/admin instead of repositories/
php artisan goat:make Hello --paths=repository=app/Repo/Admin,model=app/Domain/Models --force
# → app/Repo/Admin/HelloRepository.php (App\Repo\Admin) + app/Domain/Models/Hello.php
php artisan goat:make World --module=Admin --force
# → app/Modules/Admin/Models/World.php + app/Modules/Admin/Repositories/...
# interactive: after schema preview GOAT asks “Customize output paths?” → type per component

📁 Custom paths — you choose where files go

No more locked app/Repositories. Put any artifact anywhere — per run, no config edit needed:

# single: repo/Admin instead of repositories/
php artisan goat:make Hello --paths=repository=app/Repo/Admin --force
# → app/Repo/Admin/HelloRepository.php (namespace App\Repo\Admin auto)

# multiple: split models & repos
php artisan goat:make Hello --paths=repository=app/Repo/Admin,model=app/Domain/Models --force
# → app/Domain/Models/Hello.php (App\Domain\Models)

# module: group everything under app/Modules/{Module}
php artisan goat:make World --module=Admin --force
# → app/Modules/Admin/Models/World.php
#   app/Modules/Admin/Repositories/WorldRepository.php
#   app/Modules/Admin/Services/WorldService.php
#   tests/Feature/Modules/Admin/WorldTest.php

# interactive: no flags → after schema GOAT asks “Customize output paths?” → y → type per component
php artisan goat:make Product

--paths is key=path comma-separated (model,migration,request,resource,controller,service,repository,policy,test). Paths can be absolute or app/... relative — namespaces inferred automatically (app/Repo/AdminApp\Repo\Admin). For permanent change, publish config/goat.php.


🧬 Inputs — Migration or ERD → one schema

Migration — understands Blueprint: id, string, text, integer, bigInteger, decimal, float, boolean, date, datetime, timestamp, foreignId, uuid, json, enum, softDeletes, timestamps, unique, nullable, default, constrained, index

ERD — plain text, forgiving:

inventories
------------
id bigint PK
product_name varchar
sku varchar UNIQUE
quantity integer
price decimal(10,2)
created_at timestamp

No type? Inferred (quantityinteger, pricedecimal, descriptiontext). Handles PK, FK -> categories.id, UNIQUE, DEFAULT 0, varchar(100).

products
---------
id bigint PK
category_id bigint FK -> categories.id
name varchar
price decimal(10,2)

categories
----------
id bigint PK
name varchar

GoatSchema is the single source of truth — parsers feed it, 9 generators consume it.


🧩 What gets generated

Product.phpfillable, casts, belongsTo(Category::class)

protected $fillable = ['category_id','name','price'];
protected function casts(): array { return ['price' => 'decimal:2']; }
public function category(){ return $this->belongsTo(Category::class,'category_id'); }

Requestsrequired/sometimes + string/integer/numeric/exists:categories,id/unique + max:255 Controller — thin index/store/show/update/destroy, delegates to ProductService, uses ProductResource Service ↔ Repository — business vs query split, paginate/all/find/create/update/delete PolicyviewAny/view/create/update/delete/restore/forceDelete (edit stub to fit) Testtest_can_list_productstest_can_delete_product with factory payloads


🎨 Customize Everything

// config/goat.php
return [
  'paths' => [
    'model' => app_path('Models'),
    'migration' => database_path('migrations'),
    'request' => app_path('Http/Requests'),
    'resource' => app_path('Http/Resources'),
    'controller' => app_path('Http/Controllers'),
    'service' => app_path('Services'),
    'repository' => app_path('Repositories'),
    'policy' => app_path('Policies'),
    'test' => base_path('tests/Feature'),
  ],
  'namespaces' => ['model' => 'App\\Models', /* ... */],
  'generate' => ['model'=>true, /* ... */],
];

Stubs — one per artifact:

stubs/model.stub, migration.stub, request.stub, resource.stub,
      controller.stub, service.stub, repository.stub, policy.stub, test.stub
php artisan vendor:publish --tag=goat-stubs
# → resources/stubs/vendor/goat/*.stub — edit once, generate forever

StubRenderer prefers your published stub, falls back to package default.


🛡️ Safety & DX

  • Never overwrites without --force⚠ Product.php already exists. Use --force
  • Validates --only/--except, empty input, unsupported types, bad table names — no stack trace dumps
  • Naming via NameResolver (productsProduct, product_itemsProductItem, category_idcategory)
  • --only=model,resource --except=policy composable

🏗️ Architecture — 2026

src/
├── Commands/MakeCommand.php          # UX, STDIN, --from/--only/--except/--force
├── Parsers/MigrationParser.php       # Blueprint → GoatSchema
│        ErdParser.php                # ERD → GoatSchema (infer types)
├── Schema/GoatSchema|Table|Column|Relationship  # ← single source
├── Generators/* (9)                  # Model/Migration/Request/Resource/Controller/Service/Repository/Policy/Test
├── Support/NameResolver|StubRenderer|FileWriter|GoatConfig
└── GoatServiceProvider.php           # config + publish + command

No giant generator. Each artifact isolated, stub-driven, testable.


🧪 Tests

composer install
composer test # vendor/bin/phpunit — 40 tests

Covers: migration/ERD parsing, columns, relationships, naming, 9 generators, CLI, --only/--except/--force, file protection, stubs.


📦 Install (GitHub)

composer config repositories.goat vcs https://github.com/CodeWithTeds/meehh.git
composer require meehh/laravel-goat:@dev --dev

Once on Packagist: composer require meehh/laravel-goat --dev

Requires PHP ^8.3 · Laravel 11|12|13


🗺️ Roadmap

  • --api / --web presets, enum casts, factories, --all for multi-table ERD, goat:make --from=openapi

PRs welcome. Build your next feature with php artisan goat:make.


Built for builders who ship features, not boilerplate.

MIT · Owned by Prof Alex Software Dev / TE-AD · github.com/CodeWithTeds/meehh · Report issue · php artisan goat:make