AI code generation is best at the repetitive parts of a project: migrations, models, form fields, test scaffolding and boilerplate. It’s weakest where the code depends on the business, its security and its data. Give the model your project’s conventions, ask for one layer at a time, and review what it writes as you would a pull request.
Preparation does most of the work. A project documentation scaffold gives the model your architecture before it writes anything.
This guide covers code generation on Laravel, Shopify and WordPress projects, with examples and the checks that catch what the model gets wrong.
What to hand over, and what to keep
What AI does well
Models are good at patterns and repetition. They can write:
- Structural code: migrations, models, controllers, routes and configuration
- Boilerplate: CRUD operations, API endpoints and authentication scaffolding
- Repeated components: form fields, table columns, list items and card layouts
- Tests: unit, feature and integration tests for existing code
- Documentation: inline comments, README files and API documentation
- Conversions: moving code between languages, frameworks or patterns
What needs a person
Models struggle with:
- Business logic: the rules and constraints particular to your business
- Security: authentication, authorisation and encryption
- Performance: indexing strategy and caching layers
- Architecture: system design and technology choices
- Code that depends on the rest of the application: anything that needs the whole system in mind
Let the model save you typing, and keep the decisions with a person.
Where it saves the most time
Laravel development
Database layer:
Generate a Laravel migration and model for a blog post system.
Requirements:
- Posts table with: title, slug, content, excerpt, status, published_at
- Categories table with: name, slug, description
- Many-to-many relationship between posts and categories
- Soft deletes on posts
- Indexes on slug and published_at fields
- Model should include relationships, scopes, and accessors
The model writes:
// Migration
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->string('slug')->unique();
$table->text('content');
$table->text('excerpt')->nullable();
$table->enum('status', ['draft', 'published', 'archived'])->default('draft');
$table->timestamp('published_at')->nullable();
$table->timestamps();
$table->softDeletes();
$table->index('slug');
$table->index('published_at');
});
Schema::create('categories', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('slug')->unique();
$table->text('description')->nullable();
$table->timestamps();
});
Schema::create('category_post', function (Blueprint $table) {
$table->foreignId('category_id')->constrained()->onDelete('cascade');
$table->foreignId('post_id')->constrained()->onDelete('cascade');
$table->primary(['category_id', 'post_id']);
});
}
// Model
class Post extends Model
{
use HasFactory, SoftDeletes;
protected $fillable = [
'title', 'slug', 'content', 'excerpt', 'status', 'published_at'
];
protected $casts = [
'published_at' => 'datetime',
];
// Relationships
public function categories()
{
return $this->belongsToMany(Category::class);
}
// Scopes
public function scopePublished($query)
{
return $query->where('status', 'published')
->whereNotNull('published_at')
->where('published_at', '<=', now());
}
// Accessors
public function getExcerptAttribute($value)
{
return $value ?? Str::limit(strip_tags($this->content), 150);
}
}
Even this short example has a flaw. slug already has a unique index, so index('slug') adds a second, duplicate index that slows every insert. It looks right and runs fine, which is exactly why generated code needs review.
For the relationships themselves, see advanced Eloquent relationships, and for indexes, Laravel performance optimisation.
API controllers:
Generate a Laravel API controller for posts with:
- Resource responses
- Validation
- Policy authorisation
- Query optimisation
- Error handling
This gives you a first draft of the controller structure. Review it as you would a junior developer’s pull request before it goes anywhere near production.
Shopify theme development
Liquid sections:
Generate a Shopify section for a featured products carousel.
Settings:
- Collection selector
- Number of products (1-10)
- Layout: grid or carousel
- Show prices: yes/no
- Button text (customisable)
Output as complete section with schema.
The model writes the Liquid template, the CSS and the JSON schema. Check the result against Shopify theme performance before it ships.
Shopify Functions:
Generate a Shopify discount Function for tiered quantity discounts:
- Buy 3+ items, get 10% off
- Buy 5+ items, get 15% off
- Buy 10+ items, get 20% off
Apply to products in one collection only
Shopify Scripts stopped running on 30 June 2026, so ask for a Function, not a Script. Models trained on older material still suggest Scripts.
For the API side, see Shopify API integration.
WordPress development
Custom post types:
Generate WordPress custom post type registration for "Case Studies" with:
- Custom taxonomies: Industry, Service
- Custom fields (ACF): Client name, project duration, results
- Archive template structure
- Single template structure
The model writes the registration code, the templates and the field definitions. The WordPress hook system post covers wiring them in.
Plugin scaffolding:
Generate WordPress plugin boilerplate for "Advanced Contact Form" with:
- Admin settings page
- Shortcode support
- Email notifications
- Database table for submissions
- AJAX form submission
Then check it against WordPress plugin performance.
Prompt templates
Structured request format
The same format every time gives more predictable output:
Task: [What you want generated]
Context: [Framework version, dependencies, constraints]
Requirements: [Specific features, patterns, standards]
Output Format: [Code only, with comments, with tests]
Constraints: [What to avoid, what to include]
Laravel controller example
Task: Generate Laravel resource controller for Product model
Context: Laravel 12, using API resources, JSON responses
Requirements:
- Index with pagination (15 per page)
- Store with validation
- Show with relationships (category, images)
- Update with authorisation
- Destroy with soft delete
Output Format: Complete controller with comments
Constraints:
- Use dependency injection
- Include type hints
- Follow PSR-12
A structured request gives more consistent code, which still needs review. Prompt engineering best practices covers the techniques behind it.
TypeScript component example
Task: Convert React component to TypeScript
Context: React 18, using hooks
Requirements:
- Preserve all functionality
- Add proper type definitions
- Include prop types and return types
- Add JSDoc comments
Output Format: Complete TypeScript component
Constraints:
- Use functional components
- Avoid 'any' type
- Enable strict mode compatibility
Code quality and safety
Automated review tooling
Run the same checks on generated code as on your own, before every commit:
PHP/Laravel:
# Static analysis
./vendor/bin/phpstan analyse --level=8
# Code style
./vendor/bin/php-cs-fixer fix --dry-run
# Known vulnerabilities in dependencies
composer audit
# Tests
php artisan test
JavaScript/TypeScript:
# Linting
npm run lint
# Type checking
npm run type-check
# Tests
npm test
# Build verification
npm run build
WordPress:
# WordPress Coding Standards
phpcs --standard=WordPress
# PHP compatibility
phpcs -p . --standard=PHPCompatibilityWP
# Known vulnerabilities in dependencies
npm audit
Security checklist
Before committing AI-generated code, verify:
- No hardcoded credentials or API keys
- Input validation on all user data
- SQL injection prevention (parameterised queries)
- XSS protection (escaped output)
- CSRF protection on forms
- Authorisation checks
- Secure file upload handling
- Rate limiting on public endpoints
Performance validation
Check AI-generated code for:
Database queries:
- N+1 query problems
- Missing indexes
- Eager loading opportunities
- Unnecessary SELECT *
Caching:
- Cache frequently accessed data
- Implement cache invalidation
- Use appropriate cache drivers
Resource usage:
- Memory-efficient operations
- Proper pagination
- Background job usage for heavy tasks
Laravel performance optimisation and WordPress caching strategies go further on both.
Workflow integration
IDE integration
VS Code with GitHub Copilot:
- Inline suggestions and chat
- Agent mode for multi-file changes
Cursor IDE:
- Built-in AI chat
- Context-aware suggestions
- Multi-file editing
JetBrains AI Assistant:
- Code generation
- Refactoring suggestions
- Documentation generation
CLI tools
A custom Artisan command:
class GenerateAIScaffolding extends Command
{
protected $signature = 'ai:scaffold {model} {--type=crud}';
public function handle(AIService $ai)
{
$model = $this->argument('model');
$type = $this->option('type');
$prompt = PromptTemplate::scaffold($model, $type);
$code = $ai->generate($prompt);
// Validate and save
if ($this->validateCode($code)) {
$this->saveFiles($code);
$this->info("Scaffolding generated for {$model}");
}
}
}
Custom Artisan commands covers building commands like this one.
Git hooks
Pre-commit checks:
#!/bin/bash
# .git/hooks/pre-commit
# Check for AI-generated code markers
if git diff --cached | grep -q "GENERATED_BY_AI"; then
echo "AI-generated code detected. Running validation..."
# Run tests
php artisan test
# Run static analysis
./vendor/bin/phpstan analyse
if [ $? -ne 0 ]; then
echo "Validation failed. Please review AI-generated code."
exit 1
fi
fi
What this looks like in practice
The pattern in the opening section is the one I use. Teaching an AI to understand a codebase covers what happens when the conventions are missing. Ralph loop gotchas covers what goes wrong when an agent runs unattended.
Three more patterns
Tests first
Generate tests first, then code:
Generate PHPUnit tests for a Laravel service that processes customer orders.
Requirements:
- Test successful order processing
- Test validation failures
- Test payment gateway errors
- Test inventory checks
- Test email notifications
Then generate the service class that passes these tests.
Writing the tests first means:
- The code is checked against the requirements
- Edge cases are named before the code exists
- Later refactoring is checked by the same tests
- The tests document what the code does
Incremental generation
For complex features, generate in layers:
Layer 1: data structure
Generate database schema for e-commerce order system.
Include: orders, order_items, customers, addresses, payments
Layer 2: models
Generate Laravel models with relationships for the above schema.
Layer 3: business logic
Generate service classes for:
- Order creation
- Payment processing
- Inventory management
Layer 4: the API
Generate API controllers and resources for the order system.
Each layer is small enough to review, and the next prompt builds on code you’ve already checked.
Context-aware generation
Include project-specific patterns in the prompt, or let the tool read them from the repository:
Generate a new Laravel controller following our project patterns.
Project context:
${projectGuidelines}
${existingControllerExamples}
Generate controller for: ${modelName}
Keeping context small
Send less context:
// Less efficient
"Here's my entire 5000-line codebase... now generate a new controller"
// More efficient
"Generate controller following this pattern: [paste single example controller]"
Batch related files: Generate multiple related files in one request:
Generate these Laravel files in one response:
1. Model: Product
2. Migration for products table
3. Factory for testing
4. Resource for API
5. FormRequest for validation
Ensure all files work together correctly.
Do and don’t
Do
Don’t
Key takeaways
- Code generation is best at patterns and repetition
- Quality and security still need a person
- Structured prompts give more consistent output
- Run tests, linters and security scans on every change
- It saves the most time on boilerplate, CRUD and scaffolding
On Laravel applications, Shopify themes and WordPress plugins alike, code generation saves time when the model has the context it needs and a person reviews every line.
More in this series
- Prompt engineering best practices: writing prompts that hold up in production
For platform-specific deep dives:
Published , updated .
Part 2 of Artificial Intelligence.