pekral/cursor-rules
Publishes ready-made Cursor IDE rules for Laravel and PHP projects, helping AI coding assistants follow your team's conventions, structure, testing, and best practices. Install via Composer and publish configurable rule files into .cursor/rules for consistent, project-aware code suggestions.
Install as a dev dependency so it never ships to production:
composer require --dev pekral/cursor-rules
Look first at what the package actually ships:
ls vendor/pekral/cursor-rules
You will typically find a .cursor/rules/ directory (or .cursorrules file) plus a README. If the package exposes a publish command via extra.laravel, run php artisan vendor:publish --provider="Pekral\\CursorRules\\..." — check vendor/pekral/cursor-rules/composer.json under extra for the exact tag.
Get the rules into your workspace. Cursor only reads rules from the project root, so copy them rather than leaving them in vendor/:
mkdir -p .cursor/rules
cp -r vendor/pekral/cursor-rules/.cursor/rules/* .cursor/rules/
First use case: open the project in Cursor, start a chat, and try something narrow but convention-heavy:
"Create a FormRequest and Controller action to store a Post, following the project's rules."
Verify the output matches the conventions in the copied rules (naming, return types, test style). That's your fastest signal the rules are being picked up.
Publish once, commit to the repo. Treat the rules as project source, not a runtime dependency. Commit .cursor/rules/*.mdc so every teammate gets identical behavior on clone — no per-developer setup drift.
Scope rules with globs. The bundled rules are usually generic Laravel/PHP conventions. Split them so they only fire where relevant to avoid polluting context on every prompt. Each .mdc file supports frontmatter like:
---
description: Controller and FormRequest conventions
globs: ["app/Http/**/*.php"]
alwaysApply: false
---
Keep broad, always-on rules (naming, architecture) in one file; scope testing rules to tests/**, migration rules to database/migrations/**, etc.
Layer project-specific overrides on top. Don't edit the published files in place if you want clean updates. Instead add your own .cursor/rules/00-project.mdc with alwaysApply: true for things the package can't know — domain terms, money-as-integer rules, service layer boundaries. Later, diff your additions against the new package version on upgrade.
Pair with your toolchain. The rules are most valuable when they mirror what Pint, PHPStan/Larastan, and Pest/PHPUnit actually enforce. If the rules say "strict types everywhere" but pint.json doesn't, Cursor will fight your CI. Cross-check the rules against your existing configs the first day and reconcile — usually by amending the rules, not loosening the toolchain.
Workflow for a feature. Use the rules to bootstrap the mechanical parts (FormRequest → Controller → Action/Service → Feature test → Factory), then review. Typical prompt shape:
"Implement
POST /postsend to end: FormRequest, controller action, service class, feature test. Follow the coding and testing rules already loaded."
The rules shine on scaffolding and consistency, less so on novel business logic.
Sync script for upgrades. Add a Composer script so re-syncing is one command, but make it non-destructive by design (diff, don't blind-overwrite):
"scripts": {
"cursor:sync": "rsync -av --ignore-existing vendor/pekral/cursor-rules/.cursor/rules/ .cursor/rules/"
}
vendor/ are invisible to Cursor. This is the #1 mistake. Cursor does not scan dependencies; if you only run composer require, nothing changes in chat behavior. You must copy/publish into .cursor/rules/ at the repo root and commit..cursorrules vs .cursor/rules/*.mdc. Older Cursor versions read only a single root .cursorrules file; newer ones prefer the directory of .mdc files. Check what your Cursor build expects. If the package ships a legacy file, that's a hint about the era it was authored in — you may need to convert frontmatter before it activates.--- block or a typo in globs/alwaysApply silently disables the rule. When a rule "isn't working," open the file and validate the header before blaming the model.alwaysApply: true. Marking every rule as always-on burns context and dilutes focus. Prefer glob-scoped rules and reserve always-on for a small handful of non-negotiables (strict types, directory layout).readonly suggestions that won't compile. Edit the rules to state your actual composer.json php constraint and Pint's preset.--force wipes your local amendments. Always diff (git diff after sync) and keep your deltas in a separate file so upstream updates merge cleanly.How can I help you explore Laravel packages today?