PHPackages                             sagor110090/laravel-vue-api-crud-generator - 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. sagor110090/laravel-vue-api-crud-generator

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

sagor110090/laravel-vue-api-crud-generator
==========================================

Creates a basic skeleton for a CRUD app in both Laravel &amp; Vue.js single file components.

020Blade

Since Dec 25Pushed 4y ago2 watchersCompare

[ Source](https://github.com/sagor110090/laravel-crud-generator-vue-api)[ Packagist](https://packagist.org/packages/sagor110090/laravel-vue-api-crud-generator)[ RSS](/packages/sagor110090-laravel-vue-api-crud-generator/feed)WikiDiscussions master Synced yesterday

READMEChangelogDependenciesVersions (1)Used By (0)

Laravel Vue API Crud Generator
------------------------------

[](#laravel-vue-api-crud-generator)

#### Overview

[](#overview)

A Laravel package that lets you generate boilerplate code for a Vue.js/Laravel app. Simply enter the name of a database table and based on that it will create:

- A Laravel model
- A Laravel controller (with get, list, create, update, delete as well as validation based on a chosen DB table)
- Laravel routes (get, list, create, update, delete)
- 2 Vue.js single file components to create, update, list, delete and show (using Vform &amp; axios)

This package aims to speed up the process of communicating between backend (Laravel) and frontend (Vue.js).

### Installation

[](#installation)

`composer require sagor110090/laravel-vue-api-crud-generator`

Usage
-----

[](#usage)

Firstly you should create a new migration in the same way that you usually would. For example if creating a posts table use the command

`php artisan make:migration create_posts_table`

Then in your migration file add your fields as usual

```
Schema::create('posts', function (Blueprint $table) {
    $table->id();
    $table->string('title',200);
    $table->text('content')->nullable();
    $table->timestamps();
});

```

Then run the migrate command to create the posts table

`php artisan migrate`

Once you have done that you just need to run one `vueapi` command. Add the name of your table to the end of the command so in this case it's posts.

`php artisan vueapi:generate posts`

This will then generate all the files mentioned above.

Once you have run this command, using the `posts` example above, it will create the following boilerplate files:

### Routes

[](#routes)

Based on a `posts` DB table it will produce these routes

```
Route::get('posts', 'PostsController@list');
Route::get('posts/{id}', 'PostsController@get');
Route::post('posts', 'PostsController@create');
Route::put('posts/{id}', 'PostsController@update');
Route::delete('posts/{id}', 'PostsController@delete');

```

### Controller

[](#controller)

Based on a `posts` DB table it will produce this controller

```

```

### Model

[](#model)

Based on a `posts` DB table it will produce this model

```

```

### Vue (List template)

[](#vue-list-template)

Based on a `posts` DB table it will produce this Vue.js list single file component (Posts-list.vue)

```

          Create post

                  title

                  content

                  meta_description

                {{ (form.busy) ? 'Please wait...' : 'Submit'}}

          List posts

              post {{ index }}

              {{ (form.busy) ? 'Please wait...' : 'Delete'}}

          Loading...
          No posts exist

import { Form, HasError, AlertError } from 'vform'
export default {
  name: 'Post',
  components: {HasError},
  data: function(){
    return {
      posts : false,
      form: new Form({
          "id" : "",
          "title" : "",
          "content" : "",
          "meta_description" : "",
          "created_at" : "",
          "updated_at" : "",
      })
    }
  },
  created: function(){
    this.listPosts();
  },
  methods: {
    listPosts: function(){

      var that = this;
      this.form.get('/posts').then(function(response){
        that.posts = response.data;
      })

    },
    createPost: function(){

      var that = this;
      this.form.post('/posts').then(function(response){
        that.posts.push(response.data);
      })

    },
    deletePost: function(post, index){

      var that = this;
      this.form.delete('/posts/'+post.id).then(function(response){
        that.posts.splice(index,1);
      })

    }
  }
}

.posts{
    margin:0 auto;
    width:700px;
    display:flex;
    .half{
      flex:1;
      &:first-of-type{
        margin-right:20px;
      }
    }
    form{
      .form-group{
        margin-bottom:20px;
        label{
          display:block;
          margin-bottom:5px;
          text-transform: capitalize;
        }
        input[type="text"],input[type="number"],textarea{
          width:100%;
          max-width:100%;
          min-width:100%;
          padding:10px;
          border-radius:3px;
          border:1px solid silver;
          font-size:1rem;
          &:focus{
            outline:0;
            border-color:blue;
          }
        }
        .invalid-feedback{
          color:red;
          &::first-letter{
            text-transform:capitalize;
          }
        }
      }
      .button{
        appearance: none;
        background: #3bdfd9;
        font-size: 1rem;
        border: 0px;
        padding: 10px 20px;
        border-radius: 3px;
        font-weight: bold;
        &:hover{
          cursor:pointer;
          background: darken(#3bdfd9,10);
        }
      }
    }
}

```

### Vue (Single template)

[](#vue-single-template)

Based on a `posts` DB table it will produce this Vue.js single file component (Posts-single.vue)

```

        Update Post

          < Back to posts

                  title

                  content

                  meta_description

              {{ (form.busy) ? 'Please wait...' : 'Update'}}
              {{ (form.busy) ? 'Please wait...' : 'Delete'}}

        Loading post...

import { Form, HasError, AlertError } from 'vform'
export default {
  name: 'Post',
  components: {HasError},
  data: function(){
    return {
      loaded: false,
      form: new Form({
          "id" : "",
          "title" : "",
          "content" : "",
          "meta_description" : "",
          "created_at" : "",
          "updated_at" : "",

      })
    }
  },
  created: function(){
    this.getPost();
  },
  methods: {
    getPost: function(Post){

      var that = this;
      this.form.get('/posts/'+this.$route.params.id).then(function(response){
        that.form.fill(response.data);
        that.loaded = true;
      }).catch(function(e){
          if (e.response && e.response.status == 404) {
              that.$router.push('/404');
          }
      });

    },
    updatePost: function(){

      var that = this;
      this.form.put('/posts/'+this.$route.params.id).then(function(response){
        that.form.fill(response.data);
      })

    },
    deletePost: function(){

      var that = this;
      this.form.delete('/posts/'+this.$route.params.id).then(function(response){
        that.form.fill(response.data);
        that.$router.push('/posts');
      })

    }
  }
}

.PostSingle{
  margin:0 auto;
  width:700px;
  form{
    .form-group{
      margin-bottom:20px;
      label{
        display:block;
        margin-bottom:5px;
        text-transform: capitalize;
      }
      input[type="text"],input[type="number"],textarea{
        width:100%;
        max-width:100%;
        min-width:100%;
        padding:10px;
        border-radius:3px;
        border:1px solid silver;
        font-size:1rem;
        &:focus{
          outline:0;
          border-color:blue;
        }
      }
      .button{
        appearance: none;
        background: #3bdfd9;
        font-size: 1rem;
        border: 0px;
        padding: 10px 20px;
        border-radius: 3px;
        font-weight: bold;
        &:hover{
          cursor:pointer;
          background: darken(#3bdfd9,10);
        }
      }
      .invalid-feedback{
        color:red;
        &::first-letter{
          text-transform:capitalize;
        }
      }
    }
  }
}

```

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

[](#configuration)

Here are the configuration settings with their default values.

```

```

To copy the config file to your working Laravel project enter the following artisan command

`php artisan vendor:publish --provider="sagor110090\vueApi\vueApiServiceProvider" --tag="config"`

##### model\_dir

[](#model_dir)

Specifies the location where the generated model files should be stored

#### controller\_dir

[](#controller_dir)

Specifies the location where the generated controller files should be stored

#### vue\_files\_dir

[](#vue_files_dir)

Specifies the location where the Vue single file templates should be stored

#### vue\_url\_prefix

[](#vue_url_prefix)

Specifies what prefix should be added to the URL in your view files. The default is `/api` ie `/api/posts`

#### routes\_dir

[](#routes_dir)

Specifies the location of the routes directory

#### routes\_file

[](#routes_file)

Specifies the name of the routes file

### Customising the templates

[](#customising-the-templates)

If you use another frontend framework such as React or you want to adjust the structure of the templates then you can customise the templates by publishing them to your working Laravel project

`php artisan vendor:publish --provider="lummy\\vueApi\\vueApiServiceProvider" --tag="templates"``

They will then appear in

`\resources\views\vendor\vueApi`

### Variables in the templates

[](#variables-in-the-templates)

Each template file passes a data array with the following fields

##### $data\['singular'\]

[](#datasingular)

The singular name for the DB table eg Post

##### $data\['plural'\]

[](#dataplural)

The plural name for the DB table eg Posts

##### $data\['singular\_lower'\]

[](#datasingular_lower)

The singular name for the DB table (lowercase) eg post

##### $data\['plural\_lower'\]

[](#dataplural_lower)

The plural name for the DB table eg (lowercase) eg posts

##### $data\['fields'\]

[](#datafields)

An array of the fields that are part of the model.

- name (the field name)
- type (the mysql varchar, int etc)
- simplified\_type (text, textarea, number)
- required (is the field required)
- max (the maximum number of characters)

### Other things to note

[](#other-things-to-note)

I have only tested this on Laravel MYSQL driver so I'm not sure if it will work on other databases.

In Vue.js files the routes are presumed to be: using the posts example. You can easily configure these from the templates generated

/posts (Posts-list.vue) /posts/{id} (Posts-single.vue)

Please feel free to contact me with any feedback or suggestions

###  Health Score

17

—

LowBetter than 6% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity6

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity31

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% 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.

### Community

Maintainers

![](https://www.gravatar.com/avatar/99445e20972ed9112b4b2be64575c9ed21fe6fdb385d828429159019deaf8b1e?d=identicon)[sagor110090](/maintainers/sagor110090)

---

Top Contributors

[![sagor110090](https://avatars.githubusercontent.com/u/23266843?v=4)](https://github.com/sagor110090 "sagor110090 (12 commits)")

### Embed Badge

![Health badge](/badges/sagor110090-laravel-vue-api-crud-generator/health.svg)

```
[![Health](https://phpackages.com/badges/sagor110090-laravel-vue-api-crud-generator/health.svg)](https://phpackages.com/packages/sagor110090-laravel-vue-api-crud-generator)
```

###  Alternatives

[leafo/lessphp

lessphp is a compiler for LESS written in PHP.

2.2k8.2M141](/packages/leafo-lessphp)[chelout/laravel-relationship-events

Missing relationship events for Laravel

5252.3M17](/packages/chelout-laravel-relationship-events)[marcocesarato/php-conventional-changelog

Generate changelogs and release notes from a project's commit messages and metadata and automate versioning with semver.org and conventionalcommits.org

2511.3M109](/packages/marcocesarato-php-conventional-changelog)[larapack/dd

`dd` is a helper method in Laravel. This package will add the `dd` to your application.

1162.5M432](/packages/larapack-dd)[idiosyncratic/editorconfig

PHP implementation of EditorConfig

191.9M1](/packages/idiosyncratic-editorconfig)

PHPackages © 2026

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