amjadiqbal/laravel-ninja-keys
Laravel Ninja Keys adds a fast keyboard-driven command palette to Laravel apps, letting users search and run actions, navigate pages, and trigger shortcuts through an elegant Ninja Keys interface with simple configuration.
<x-ninja-keys />) or directive, no custom JS bundling, no frontend build-pipeline work required.href() / route() actions, data-ninja-keys-open click triggers, and submenu support let you expose navigation and multi-step action trees without designing new navigation UI. Good fit for internal tools, admin panels, back-office SaaS, and any product where "expert users want to stop clicking."onSelected and render-time NinjaKeys::define() callbacks exist, and per-page overrides are component attributes — so PMs can scope per-page palettes (e.g. a different action set on a billing page vs. an inbox) without new engineering architecture.searchPlaceholder, per-page overrides, and programmatic open triggers are enough to A/B a "press ⌘K" hint, an empty-state prompt, or a contextual palette on a specific workflow — cheap experiments, measurable in feature-adoption and time-to-task.Adopt when most of the following hold:
laravel-assets, Livewire navigate() integration, and wire:navigate hotkey de-duplication. In an Inertia/React/Vue SPA you would get more control (and less indirection) by using ninja-keys or cmdk directly.Look elsewhere or defer when:
dev-main. This is effectively a breaking release: config keys use_cdn/asset_path became script/asset_url, hotKeys/searchPlaceholder/noHeader were removed, the publish tag changed to ninja-keys-config, and actions missing id or title now throw InvalidArgumentException instead of silently degrading. Budget a migration pass and an audit of every registered action, not a composer update.For executives (one paragraph): A command palette is the cheapest credible "this product is fast" signal we can ship — it's what users associate with Linear, Notion, and Raycast. This package lets us deliver that in days rather than weeks, on top of our existing Laravel stack, with no new frontend framework, no new build pipeline, and no third-party CDN in the critical path. It just hit a stable 1.0: versioned API, self-hosted assets, CSP-compliant script loading, per-role action filtering, and compatibility with our long-running worker setup. The main cost is not engineering — it's a Laravel 12/13 and PHP 8.3 baseline, which should be sequenced against our existing upgrade plan rather than treated as a palette-only decision.
For engineering leads: v1.0.0 closes the reasons we'd have said no. The three upstream bugs that make hand-rolled palettes flaky are fixed in-package: the action.handler is not a function failure (handler was being passed by name), nested-action tree flattening (ninja-keys 1.2.2 silently moved root actions into submenus), and the regex SyntaxError on every keystroke when typing ( or [. wire:navigate no longer double-fires stale hotkeys, and the manager is per-request scoped so Octane is safe. Assets are a single pinned ES module published to public/vendor/ninja-keys with a jsDelivr fallback only until published — no unpkg mixed-Lit resolution risk. CSP nonces are applied to both scripts and there's a php artisan about entry for support triage. The trade-off we're accepting: a Laravel 12/13 + PHP 8.3 floor, and a config surface that renamed use_cdn/asset_path to script/asset_url and dropped hotKeys, searchPlaceholder, and noHeader.
Risks and how to frame them:
dev-main must treat this as breaking: renamed config keys, new config publish tag (ninja-keys-config), and actions without id or title now throwing instead of failing silently. That last one is arguably a feature — it surfaces broken registrations at render time — but it will page someone on day one if we don't audit.public/vendor/ninja-keys ships; the jsDelivr fallback is a stopgap.Effort estimate: hours to a first palette; one to two days for a permission-scoped, per-page action set with tests; the real cost is the framework/PHP baseline upgrade, which should be justified on its own merits.
How can I help you explore Laravel packages today?