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

Peep Laravel Package

shibbirweb/peep

Peep is a lightweight Laravel package from shibbirweb that gives developers a quick, simple way to peek into their application during development. Easy to install and use, it helps surface useful information for local debugging and inspection.

View on GitHub
Deep Wiki
Context7

Getting Started

  • Install the client in the app you want to inspect: composer require shibbirweb/peep --dev. The Laravel adapter is auto-discovered (Laravel 5.5 → 13), registers its watchers, and is disabled by default in production.
  • Enable it for local work: publish/create config/peep.php and turn it on, or set PEEP_ENABLED=true in .env. It stays off unless enabled — nothing is sent anywhere until you flip it.
  • Start a viewer. Two options:
    • CLI: vendor/bin/peep-server serve --open=browser (viewer package requires PHP 8.5; your app can stay on 7.1+).
    • Desktop app (macOS/Windows/Linux): native window with its own bundled PHP 8.5, tray with unread count, hotkey, always-on-top, native notifications, peep://open for serve --open=window.
  • First call — drop it in a controller or Artisan command:
    peep($user);                       // value tree with visibility/redaction
    peep()->label('checkout')->large();
    User::with('orders')->get()->peep();
    
    Cards appear grouped under the current request/job/command, with the file, line and function that called them.
  • Where to look next: the wiki in docs/wiki (getting started, Laravel, query debugging, mail/SMS, webhooks, troubleshooting). docs/protocol.md is the reference if you want to build your own client.

Daily-driver first use case: you have a slow endpoint and a fat query log — open the viewer, hit the toolbar's slow switch (> 100ms), and the running app starts filtering queries within seconds without a redeploy.

Implementation Patterns

Debugging a request without dd()

  • ->peep() hangs off collections, strings, query builders and test responses; it returns the receiver, so it drops into existing chains.
  • peep()->showQueries() turns on query cards for the current request; the viewer's toolbar switches (all / slow / duplicates) are pushed to running apps through GET /_peep/switches, so you can change the lens mid-session.
  • Query cards inline their bindings, so you read the actual SQL rather than a ? soup.

Blade and views

  • @peep($var), @peepAll($loop->all()), and @peepMeasure('render') … @endPeepMeasure for timing a block without editing PHP.
  • View cards are captured by a watcher, so you can see which template rendered and how often.

Mail and notifications

  • Set MAIL_MAILER=peep and every mailable lands in the inbox instead of SMTP: HTML at desktop and mobile width, text, source, headers, attachment download, unread counts, and a link back to the request that sent it.
  • peep()->mailable($mailable) and peep()->markdown($mailable) preview a mailable before sending — the fastest way to check copy and layout.
  • SMTP on port 23525, a Mailgun-compatible API and /_peep/mail are there if you can't change the mailer. peep()->sms() covers SMS; Twilio/Vonage API-compatible endpoints answer like the real ones, and Laravel SMS notifications can optionally block the real send.

Webhooks you can actually test against

  • The simulator calls your app back when a mail/SMS is caught (or by hand from the inbox): timed steps, JSON/form/XML/raw bodies, a template language ({{ mail.message_id }}, {{ now.unix_float }}, hmac_sha256(...)), Mailgun/Twilio/Vonage presets and signatures the providers' own SDK checks accept, retries, a delivery log with resend, and import/export of rule sets. This replaces ngrok + a prayer for signature verification work.

Test suite integration

  • ->peep() on test responses makes a failing assertion inspectable after the fact.
  • peep()->count()/counterValue(), measure(), once(), limit(), rateLimiter(), if()/showIf() keep noisy loops from flooding the viewer.
  • Because a closed viewer is skipped for ~30s at ~3ms per 100 calls, leaving calls in a test run is cheap — but see the cleanup tooling below.

Non-Laravel and multi-app setups

  • Bridges exist for plain PHP, Symfony, Slim and WordPress: PSR-3 PeepLogger, PeepHandlerFactory::create() for Monolog (1→3), DumpHandler for VarDumper (3.4→8.x), opt-in casters via serializer: var-dumper, and an error handler for warnings, uncaught exceptions and fatals.
  • peep.phar install uses auto_prepend_file to load Peep into every script of a PHP install; projects with Composer keep their own version. uninstall and status to reverse/inspect.
  • Projects get their own tab in the viewer with a card count, so one viewer can serve several apps at once.

Shipping

  • vendor/bin/peep-clean (and php artisan peep:clean) lists peep(), pd(), ->peep() and @peep calls and removes the safe ones with --fix; add phpstan/rules.neon to CI so a leftover peep() fails the build instead of reaching production.

Gotchas and Tips

  • Beta. v0.1.0-beta.1 is the first public cut; pin an exact version in composer.json and expect payload/API churn. Protocol v1 is specified, so viewer-and-client drift should be detectable rather than silent, but the PHP API surface is not frozen.
  • Two PHP versions, one product. The client supports PHP 7.1+, but peep-server needs PHP 8.5. If your dev box can't run 8.5, use the desktop app (bundled PHP) instead of fighting the CLI viewer.
  • Nothing shows up? Work through: is it enabled (PEEP_ENABLED / peep.php) are you in production (disabled by default), is the viewer actually listening, is the app pointed at the right host/port. A closed viewer is intentionally silent — there's no exception to grep for, which reads as "the package is broken" when it's working as designed.
  • Docker and remote apps. The viewer listens on loopback by default. To accept apps from another machine or Linux Docker, set a token: PEEP_TOKEN in the app (token in config/peep.php), sent as X-Peep-Token; only then does the viewer bind beyond loopback, and its UI page stays local. Also set path mappings in Settings so origin links open the right file locally instead of a container path.
  • peep() returns the Peep instance, not your value. Don't inline it where the value is consumed — assign first, then peep($value). pd() dies; send() is the non-dying send.
  • Fatal/backtrace quality depends on PHP. PHP 8.5 gets fatal-error backtraces; older runtimes give you less. Don't expect parity across the 40 CI combinations.
  • History needs pdo_sqlite. Without it, cards vanish on viewer restart. Cards-per-project, history and notifications live in settings.json on the viewer, not in the app — serve reads them when no CLI option is given, so a stale settings file can quietly override your flags.
  • The viewer is a surface. Host header check (DNS rebinding), Origin check, a required UI header for UI actions, CSP, and sandboxed frames for HTML payloads are all deliberate. If you reverse-proxy it, preserve the Host/Origin or UI actions will be rejected — that's the security model, not a bug.
  • Clean up before merging. peep-clean is conservative about which calls it deems "safe"; review the --fix diff, and rely on the PHPStan rule for the stragglers. The serializer already redacts sensitive keys and reads private properties without side effects, but a peep($request->all()) in a controller is still a habit worth killing.
  • Extension points worth knowing: macros, sendCustom() for your own payload types, serializer: var-dumper casters, and the protocol spec if you want a card renderer the bundled viewer doesn't have.
  • Use --exit-with=<pid> when launching the viewer from a test runner or dev script so it shuts down with the process rather than accumulating orphaned servers on port contention.
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.
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
cgv/localized-resource