Imported from LaravelDaily/nativephp-larapackagehunt (
AGENTS.md). Install upstream withnpx skills add LaravelDaily/nativephp-larapackagehunt. Copyright stays with the author.
Laravel Boost Guidelines
The Laravel Boost guidelines are specifically curated by Laravel maintainers for this application. These guidelines should be followed closely to ensure the best experience when building Laravel applications.
Foundational Context
This application is a Laravel application and its main Laravel ecosystems package & versions are below. You are an expert with them all. Ensure you abide by these specific packages & versions.
- php - 8.5
- laravel/framework (LARAVEL) - v13
- laravel/prompts (PROMPTS) - v0
- livewire/livewire (LIVEWIRE) - v4
- larastan/larastan (LARASTAN) - v3
- laravel/boost (BOOST) - v2
- laravel/mcp (MCP) - v0
- laravel/pail (PAIL) - v1
- laravel/pint (PINT) - v1
- laravel/sail (SAIL) - v1
- pestphp/pest (PEST) - v5
- phpunit/phpunit (PHPUNIT) - v13
- tailwindcss (TAILWINDCSS) - v4
Skills Activation
This project has domain-specific skills available in **/skills/**. You MUST activate the relevant skill whenever you work in that domain—don't wait until you're stuck.
Conventions
- You must follow all existing code conventions used in this application. When creating or editing a file, check sibling files for the correct structure, approach, and naming.
- Use descriptive names for variables and methods. For example,
isRegisteredForDiscounts, notdiscount(). - Check for existing components to reuse before writing a new one.
Verification Scripts
- Do not create verification scripts or tinker when tests cover that functionality and prove they work. Unit and feature tests are more important.
Application Structure & Architecture
- Stick to existing directory structure; don't create new base folders without approval.
- Do not change the application's dependencies without approval.
Frontend Bundling
- If the user doesn't see a frontend change reflected in the UI, it could mean they need to run
npm run build,npm run dev, orcomposer run dev. Ask them.
Documentation Files
- You must only create documentation files if explicitly requested by the user.
Replies
- Be concise in your explanations - focus on what's important rather than explaining obvious details.
=== boost rules ===
Laravel Boost
Tools
- Laravel Boost is an MCP server with tools designed specifically for this application. Prefer Boost tools over manual alternatives like shell commands or file reads.
- Use
database-queryto run read-only queries against the database instead of writing raw SQL in tinker. - Use
database-schemato inspect table structure before writing migrations or models. - Use
get-absolute-urlto resolve the correct scheme, domain, and port for project URLs. Always use this before sharing a URL with the user. - Use
browser-logsto read browser logs, errors, and exceptions. Only recent logs are useful, ignore old entries.
Searching Documentation (IMPORTANT)
- Always use
search-docsbefore making code changes. Do not skip this step. It returns version-specific docs based on installed packages automatically. - Pass a
packagesarray to scope results when you know which packages are relevant. - Use multiple broad, topic-based queries:
['rate limiting', 'routing rate limiting', 'routing']. Expect the most relevant results first. - Do not add package names to queries because package info is already shared. Use
test resource table, notfilament 4 test resource table.
Search Syntax
- Use words for auto-stemmed AND logic:
rate limitmatches both "rate" AND "limit". - Use
"quoted phrases"for exact position matching:"infinite scroll"requires adjacent words in order. - Combine words and phrases for mixed queries:
middleware "rate limit". - Use multiple queries for OR logic:
queries=["authentication", "middleware"].
Artisan
- Run Artisan commands directly via the command line (e.g.,
php artisan route:list). Usephp artisan listto discover available commands andphp artisan [command] --helpto check parameters. - Inspect routes with
php artisan route:list. Filter with:--method=GET,--name=users,--path=api,--except-vendor,--only-vendor. - Read configuration values using dot notation:
php artisan config:show app.name,php artisan config:show database.default. Or read config files directly from theconfig/directory.
Tinker
- Execute PHP in app context for debugging and testing code. Do not create models without user approval, prefer tests with factories instead. Prefer existing Artisan commands over custom tinker code.
- Always use single quotes to prevent shell expansion:
php artisan tinker --execute 'Your::code();'- Double quotes for PHP strings inside:
php artisan tinker --execute 'User::where("active", true)->count();'
- Double quotes for PHP strings inside:
=== php rules ===
PHP
- Always use curly braces for control structures, even for single-line bodies.
- Use PHP 8 constructor property promotion:
public function __construct(public GitHub $github) { }. Do not leave empty zero-parameter__construct()methods unless the constructor is private. - Use explicit return type declarations and type hints for all method parameters:
function isAccessible(User $user, ?string $path = null): bool - Use TitleCase for Enum keys:
FavoritePerson,BestLake,Monthly. - Prefer PHPDoc blocks over inline comments. Only add inline comments for exceptionally complex logic.
- Use array shape type definitions in PHPDoc blocks.
=== deployments rules ===
Deployment
- Laravel can be deployed using Laravel Cloud, which is the fastest way to deploy and scale production Laravel applications.
=== herd rules ===
Laravel Herd
- The application is served by Laravel Herd at
https?://[kebab-case-project-dir].test. Use theget-absolute-urltool to generate valid URLs. Never run commands to serve the site. It is always available. - Use the
herdCLI to manage services, PHP versions, and sites (e.g.herd sites,herd services:start <service>,herd php:list). Runherd listto discover all available commands.
=== laravel/core rules ===
Do Things the Laravel Way
- Use
php artisan make:commands to create new files (i.e. migrations, controllers, models, etc.). You can list available Artisan commands usingphp artisan listand check their parameters withphp artisan [command] --help. - If you're creating a generic PHP class, use
php artisan make:class. - Pass
--no-interactionto all Artisan commands to ensure they work without user input. You should also pass the correct--optionsto ensure correct behavior.
Model Creation
- When creating new models, create useful factories and seeders for them too. Ask the user if they need any other things, using
php artisan make:model --helpto check the available options.
APIs & Eloquent Resources
- For APIs, default to using Eloquent API Resources and API versioning unless existing API routes do not, then you should follow existing application convention.
URL Generation
- When generating links to other pages, prefer named routes and the
route()function.
Testing
- When creating models for tests, use the factories for the models. Check if the factory has custom states that can be used before manually setting up the model.
- Faker: Use methods such as
$this->faker->word()orfake()->randomDigit(). Follow existing conventions whether to use$this->fakerorfake(). - When creating tests, make use of
php artisan make:test [options] {name}to create a feature test, and pass--unitto create a unit test. Most tests should be feature tests.
Vite Error
- If you receive an "Illuminate\Foundation\ViteException: Unable to locate file in Vite manifest" error, you can run
npm run buildor ask the user to runnpm run devorcomposer run dev.
=== livewire/core rules ===
Livewire
- Livewire allow to build dynamic, reactive interfaces in PHP without writing JavaScript.
- You can use Alpine.js for client-side interactions instead of JavaScript frameworks.
- Keep state server-side so the UI reflects it. Validate and authorize in actions as you would in HTTP requests.
=== pint/core rules ===
Laravel Pint Code Formatter
- If you have modified any PHP files, you must run
vendor/bin/pint --dirty --format agentbefore finalizing changes to ensure your code matches the project's expected style. - Do not run
vendor/bin/pint --test --format agent, simply runvendor/bin/pint --format agentto fix any formatting issues.
=== pest/core rules ===
Pest
- This project uses Pest for testing. Create tests:
php artisan make:test --pest {name}. - The
{name}argument should not include the test suite directory. Usephp artisan make:test --pest SomeFeatureTestinstead ofphp artisan make:test --pest Feature/SomeFeatureTest. - Run tests:
php artisan test --compactor filter:php artisan test --compact --filter=testName. - Do NOT delete tests without approval.
=== nativephp/mobile rules ===
NativePHP Mobile
- NativePHP Mobile is a Laravel package for building fully native iOS and Android apps with PHP. Screens are rendered as real SwiftUI (iOS) and Jetpack Compose (Android) UI — driven entirely by PHP via SuperNative components and EDGE Blade elements. A full PHP runtime runs directly on the device with SQLite — no web server required.
- Documentation:
https://nativephp.com/docs/mobile/4/** - IMPORTANT: Always activate the
nativephp-mobileskill every time you work on any NativePHP functionality.
Native UI First — Always
Always build screens with native UI: NativeComponent classes registered via Route::native(), rendering EDGE
elements (native:column, native:text, native:button, …). This is the way to build NativePHP apps.
- Never scaffold new screens as web views, Blade-over-WebView pages, Livewire components, or Inertia pages.
- The web view (the
native:web-viewelement) is a legacy/edge-case escape hatch for embedding web content — never the foundation of a screen. If the user asks for a webview-based screen, build it natively with EDGE instead and explain why; only fall back to the web view if they explicitly insist. - If the app contains legacy webview screens, proactively suggest converting them to native UI (see the
nativephp-webview-to-nativeskill). - Style EDGE elements with Tailwind utility classes via
class="..."/:class="..."only — never inline CSSstyle="..."attributes or ad-hoc styling props. - Compose screens from nested child components: any
NativeComponentunderapp/NativeComponentsmounts as a tag (UserCard→<native:user-card :user="$u" key="user-{{ $u->id }}" @saved="onSaved" />) with live props, its own persistent state, andemit()events bubbling to@eventtag bindings /#[On('event')]listeners. Prefer extracting a reusable child component over duplicating Blade across screens; give list children a stable domainkey(never the loop index). - Use
native:icon(SF Symbols on iOS, Material Icons on Android) for iconography — never emoji characters in UI text, labels, or buttons, unless the user explicitly asks for emojis. Prefer the typed icon enums (App\Icons\Ios,App\Icons\Android,App\Icons\AndroidOutlined) bound via the:ios/:androidattributes, e.g.:ios="Ios::Gearshape" :android="Android::Settings", importing each enum into the view with Blade's use directive first. The enums are generated, not shipped — ifapp/Icons/doesn't exist yet, runphp artisan native-ui:generate-iconsfirst (safe to run yourself).
Theme Tokens, Font Aliases, and Layouts — the Design System Trio
Every app's visual identity belongs in config/native-ui.php (publish with
php artisan vendor:publish --tag=native-ui-config), not scattered through the markup. When building or
reviewing screens, enforce all three:
- Theme tokens over hardcoded colors. Define the palette once in the config's
themeblock, then style withbg-theme-*/text-theme-*/border-theme-*classes (bg-theme-surface,text-theme-on-surface,border-theme-outline). Never sprinklebg-[#1E2021]-style arbitrary values for what is really a theme role — they can't be re-skinned and don't get automatic dark-mode pairs. Arbitrary color values are for genuine data-driven color (per-category identity colors, map imagery, chart series), and those belong in one PHP home (an enum or model method), never inline per view. Two capabilities that prevent hex fallbacks:- The token map is open-ended. When a design needs a role the shipped set lacks (a success green, an
outline-variant), add it to bothlightanddarkblocks —bg-theme-successworks immediately; no package change required. - Theme classes take opacity modifiers just like palette classes:
bg-theme-primary/15is the correct tonal-fill idiom (applies to the dark companion too) — never approximate with a hardcoded alpha hex.
- The token map is open-ended. When a design needs a role the shipped set lacks (a success green, an
- Font aliases over file tokens. Register semantic aliases in the config's
fontsarray ('headline' => 'ArchivoNarrow-Bold','mono' => 'JetBrainsMono-Regular','default' => …for the app-wide font) and writefont="headline"in views — neverfont="ArchivoNarrow-Bold". Swapping a typeface must be a one-line config change. - Native chrome via composable chrome elements (layouts optional). Author nav bars, tab bars, fabs, and
side navs directly in the screen's Blade —
<native:top-bar>(+top-bar-action),<native:bottom-nav>(+bottom-nav-item),<native:fab>,<native:bottom-bar>,<native:side-nav>. They hoist onto the real NavigationStack/TabView chrome (edge-swipe back, predictive back, large titles, Liquid Glass/Material You), and their attributes are Blade expressions over screen state, so badges/subtitles/icons are reactive. ANativeLayout(attached viaRoute::native(...)->layout(...)orRoute::nativeGroup(...)) is optional — reach for one only when many screens share identical chrome (e.g. one tabs layout for a tab section); an inline chrome element on a screen always overrides the layout's bar for that slot. Add thecustomattribute to a chrome tag only for designs the system bars genuinely can't express — it renders in-tree as an ordinary drawn element. Never hand-roll top bars or bottom navs out of rows and pressables — that forfeits native back gestures, safe-area handling, and Liquid Glass/Material You. Chrome colors take theme tokens (inline: theme classes /theme()-fed attributes; builders:->activeColor(theme('primary'))) — never pasted hex. Bar icons take the platform enums via:ios-icon/:android-iconwith a plainiconstring as cross-platform fallback; bar fonts take config aliases (font="mono"/->font('mono')). Only screens rendered without any chrome (no layout AND no inline bars) may usesafe-areaclasses.
When a Capability Is Missing
If the app needs native functionality or a UI component that core and native-ui don't provide:
- Look for an existing plugin first. Check the plugin marketplace (
https://plugins.nativephp.com) and the official core plugins. (If a marketplace-lookup MCP tool is available in your session, use it.) - If no plugin exists, build a custom plugin with
php artisan native:plugin:create— plugins bundle Swift/Kotlin bridge functions, events, permissions, and can even ship their own native EDGE components. - Never fall back to the web view to fill a native gap. A missing capability is a reason to write a plugin, not a reason to build a webview screen.
Installing Plugins — Always Register and Verify
Requiring a plugin with Composer is NOT enough — an installed-but-unregistered plugin does nothing. Every plugin install must follow all three steps:
composer require vendor/plugin-namephp artisan vendor:publish --tag=nativephp-plugins-provider— publishes the app'sNativeServiceProvider(needed once, before the first plugin registration; harmless to re-run)php artisan native:plugin:register vendor/plugin-name— adds it to theNativeServiceProviderphp artisan native:plugin:list— verify it shows as registered
Then tell the user to rebuild with php artisan native:run (native code only compiles in at build time — do not
run this yourself). If native:run warns "The following plugins are installed but not registered", go back to
step 3.
Database Seeding — Always via Migrations
On-device there is no db:seed — NativePHP runs migrations on app start (once each, tracked, versioned).
Whenever asked to seed the database, use the migration trick: create a dedicated migration
(php artisan make:migration seed_app_settings) and put the inserts in up(). If a Seeder class helps organize
the data, still create it — but invoke it from the migration's up() (e.g. (new CategorySeeder)->run()),
never rely on db:seed being run. Seed migrations must be safe for both fresh installs and updates of existing
user databases.
Build Commands — Tell the User, Never Run
CRITICAL: Never execute any of these commands yourself. Always instruct the user to run them manually in their terminal.
| Command | Purpose |
|---|---|
php artisan native:run ios |
Compile and run on iOS simulator/device |
php artisan native:run android |
Compile and run on Android emulator/device |
php artisan native:run ios --watch |
Build, deploy, then start hot reload — all in one |
php artisan native:watch |
Hot reload (watch for file changes) |
php artisan native:open |
Open project in Xcode or Android Studio |
php artisan native:install |
Install/upgrade the native shell |
Notes:
- The
./nativeshortcut wraps thenative:namespace (./native run,./native watch). - The Vite dev server is opt-in in v4: add
--vitetonative:run/native:watchonly when the app actually uses JS/CSS HMR. Native UI screens hot-reload without Vite. npm run build -- --mode=ios|androidis only needed for apps with web-view assets — not for native UI screens.
Always ask which platform before giving any build or run command. If the user hasn't specified iOS or Android, ask: "Which platform do you want to build/test on — iOS or Android?" Never assume a platform.
When the platform is confirmed, give the relevant command(s) above and tell the user to run it in their terminal. Do not run it yourself.
RTK (Rust Token Killer) - Token-Optimized Commands
When running shell commands, always prefix with rtk. This reduces context
usage by 60-90% with zero behavior change. If rtk has no filter for a command,
it passes through unchanged — so it is always safe to use.
Key Commands
# Git (59-80% savings)
rtk git status rtk git diff rtk git log
# Files & Search (60-75% savings)
rtk ls <path> rtk read <file> rtk grep <pattern>
rtk find <pattern> rtk diff <file>
# Test (90-99% savings) — shows failures only
rtk pytest tests/ rtk cargo test rtk test <cmd>
# Build & Lint (80-90% savings) — shows errors only
rtk tsc rtk lint rtk cargo build
rtk prettier --check rtk mypy rtk ruff check
# Analysis (70-90% savings)
rtk err <cmd> rtk log <file> rtk json <file>
rtk summary <cmd> rtk deps rtk env
# GitHub (26-87% savings)
rtk gh pr view <n> rtk gh run list rtk gh issue list
# Infrastructure (85% savings)
rtk docker ps rtk kubectl get rtk docker logs <c>
# Package managers (70-90% savings)
rtk pip list rtk pnpm install rtk npm run <script>
Rules
- In command chains, prefix each segment:
rtk git add . && rtk git commit -m "msg" - For debugging, use raw command without rtk prefix
rtk proxy <cmd>runs command without filtering but tracks usage
