Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Nova Tinker Tool Laravel Package

beyondcode/nova-tinker-tool

Nova Tinker Tool adds an interactive Artisan Tinker console to Laravel Nova, letting admins run PHP and tinker commands directly from the dashboard without opening a terminal. It speeds up debugging, quick data checks, and experimentation in a familiar Nova interface.

View on GitHub
Deep Wiki
Context7

Getting Started

  • Confirm the prerequisites first. This is a Laravel Nova tool, not a stand-alone artisan command. You need a working Laravel app, a paid Nova install, and laravel/tinker present. If you're not on Nova 1–3 era, stop here — the tool predates Nova 4/5 and won't mount cleanly without patching.

  • Install: composer require beyondcode/nova-tinker-tool. Nova tool providers generally auto-discover; if not, register BeyondCode\NovaTinkerTool\NovaTinkerToolServiceProvider in config/app.php.

  • Register the tool in app/Providers/NovaServiceProvider.php:

    public function tools()
    {
        return [
            new \BeyondCode\NovaTinkerTool\NovaTinkerTool(),
        ];
    }
    
  • Where to look first: the tool class (NovaTinkerTool.php), the service provider (for route registration and any canSee/authorize hooks), and the Vue component under resources/js (for the REPL input/output shell). The whole package is ~150 lines — read it end to end before wiring it up, so you know exactly what route the front end posts to and how it hands code to Tinker.

  • First use case: open Nova → click the Tinker entry in the sidebar → run a read-only probe:

    App\Models\User::count()
    App\Models\Order::latest()->first()
    App\Models\User::find(42)->orders()->pluck('status')
    

    This is the canonical day-to-day loop: inspect a model, check a relationship, sanity-check a query — without SSH, php artisan tinker, or a deploy.

Implementation Patterns

  • Ad-hoc data inspection during triage. The highest-value daily use: a support ticket references a customer, order, or specific record ID, and you confirm state in seconds from the admin panel. Reach for it when you'd otherwise ssh into a box or add a throwaway route.

  • Query prototyping before it becomes code. Write the Eloquent query in the REPL, confirm the shape of the result, then move it into a controller/repository/command. This is where the tool actually earns its keep — it shortens the inspect → write → test loop.

  • Reproducing a customer's state. Load the exact records a reporter sees, walk the relationship graph ($order->customer->subscription->plan), and confirm whether the reported symptom is data or logic. Faster than a local seed for one-off investigation.

  • Gate it explicitly — do not rely on Nova's default. Attach a canSee/authorization closure so the tool only renders for the right person in the right environment:

    (new NovaTinkerTool())->canSee(function ($request) {
        return app()->environment('local', 'staging')
            && $request->user()?->email === '[email protected]';
    });
    

    Better yet, register the tool conditionally in tools() behind an env check, so a production deploy doesn't even carry the route.

  • Wrap executions with audit logging. Because the tool posts code to a route and returns output, add a middleware or a small wrapper around the execute endpoint that logs user, timestamp, code, result before returning. This is the difference between a governed internal tool and an unaccountable RCE.

  • Keep a team snippet file. Maintain a docs/tinker-snippets.md with the ten queries the team actually runs (find-by-email, recent failures, subscription state). Engineers paste them in rather than retyping and getting the shape subtly wrong.

  • Pair it with your incident runbook. The pattern that works: incident ticket → "confirm record state via Nova Tinker" step → documented query → escalate if the state is wrong. It shortens support turnaround without adding SSH provisioning to the on-call path.

  • Read-only by convention, not enforcement. There is no destructive-query guardrail. Enforce read-only by policy and by who has access — not by hoping people type carefully. If you need hard guards, fork it and add a statement allowlist before the code reaches Tinker.

Gotchas and Tips

  • It is remote code execution behind a web login. Every execution runs with the application's full credentials — database, filesystem, outbound HTTP. Treat it as an RCE surface, gate it to a named allowlist, and hard-exclude production in code, not in documentation.
  • Archived since 2020 — you own it the moment you install it. Last release 1.1.0 (2020-01-30), zero dependents, no upstream. composer require from Packagist is a starting point, not a dependency you can count on. Realistic model: fork into your own namespace, pin against your Nova major, own the maintenance.
  • The 1.1.0 "Tinker 2.0 support" changelog is suspect. Tinker 2.0 arrived in the Laravel 11 era — long after a 2020 archive. Verify against the actual tagged code before assuming any modern-Tinker compatibility.
  • Nova 4/5 will likely not mount it. Nova's tool API churned across majors, and the bundled Vue component predates those changes. Expect to patch service-provider registration, tool metadata, and the front-end before it renders.
  • No REPL state between requests. Each submission is a fresh PHP process — variables you define in one block don't exist in the next. Write self-contained snippets or chain everything into one submission.
  • dd() and dump() can break the UI. Output rendering is a simple shell, not a full var-dumper viewer. Prefer returning plain values (->toArray(), ->pluck('id')) to get readable output.
  • No timeout, no output cap, no cancellation. A runaway Model::all() or an accidental while loop hangs the PHP-FPM worker serving that request. Keep queries bounded with take()/limit(), and kill the worker if it wedges.
  • Fatal errors surface inconsistently. Parse errors and exceptions usually render in the panel; hard fatals can 500 the route and leave the UI blank. Check storage/logs/laravel.log when the panel goes quiet.
  • Nothing to publish. No migrations, no config file, no published assets — don't waste time looking for vendor:publish targets. Configuration is entirely code (registration and gating).
  • "Why doesn't the tool appear?" Almost always Nova registration or discovery: verify it's in NovaServiceProvider::tools(), the provider is discovered, and any canSee closure actually returns true for your user in the current environment.
  • Never enable on multi-tenant, partner-accessible, or audited Nova installs. The package's age isn't the risk — a web-reachable REPL with database access is. If policy forbids executing code from the admin UI, the decision is closed; don't run a spike to relitigate it.
  • When you outgrow it, the replacement is small. A guarded internal route wrapping Artisan::call('tinker', ['--execute' => $code]) with an explicit allowlist, env check, and audit log reproduces the useful 90% in a few dozen lines you actually own.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle