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

Laravel Demo Mode Laravel Package

lauroguedes/laravel-demo-mode

Laravel Demo Mode puts your app into a safe read-only state for public demos. It blocks destructive HTTP requests and database writes while allowing configurable exceptions, so visitors can explore without changing data. Includes middleware and helpers to detect demo mode and show a clear notice.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a small, low-traffic package (11 stars, unknown repository, score ~19/100), so treat the README and source as the source of truth before wiring it into anything real. The last release date (2026-09-26) also looks anomalous versus typical package timelines — confirm the tagged version and its Laravel compatibility before adopting.

Minimal setup:

  1. Install via Composer: composer require lauroguedes/laravel-demo-mode. The service provider should be auto-discovered; if not, register it in bootstrap/providers.php (Laravel 11+) or config/app.php.
  2. Publish config/assets (expected convention): php artisan vendor:publish --provider="Lauroguedes\DemoMode\DemoModeServiceProvider" — check the provider namespace in vendor/ first because it may differ.
  3. Read the published config (config/demo-mode.php or similar) end to end. This is where the sandboxing switches live: likely a demo database connection, queue/mail/cache drivers, and a list of blocked routes or actions.
  4. Register the middleware on the routes you want sandboxed, typically in a dedicated group:
    Route::middleware(['web', 'demo'])->group(base_path('routes/demo.php'));
    
  5. Point the demo environment at disposable infrastructure — a separate database (SQLite file or a throwaway MySQL schema), QUEUE_CONNECTION=sync or a dedicated queue, MAIL_MAILER=log, CACHE_STORE=array, and a fake/isolated filesystem disk.

First use case: a public "try it" deployment of your app where visitors can click through real screens without touching production data. Start by demoing a single read-mostly flow (dashboard + one create action) behind the middleware, then expand.

Before going further, verify in source: what the middleware actually blocks, whether it swaps DB connections or merely filters routes, and whether it ships migrations/seeders for the demo dataset.

Implementation Patterns

Dedicated route file + middleware group. Keep all demo-reachable routes in routes/demo.php under a single demo middleware group. This makes the sandbox boundary explicit and reviewable in one place rather than scattered across web.php.

Separate demo database connection. The most reliable pattern is a distinct connection in config/database.php (e.g. demo) backed by SQLite, with the package's config pointing at it. Reset the file between sessions or on a schedule rather than trying to reverse individual writes.

// config/database.php
'demo' => [
    'driver' => 'sqlite',
    'database' => storage_path('app/demo/demo.sqlite'),
    'prefix' => '',
],

Reset-on-schedule instead of reset-on-request. A scheduled command (or the package's reset command, if provided) that re-runs migrate:fresh --seed --database=demo every N minutes is far more robust than per-request cleanup. Per-request teardown breaks under concurrency and queue workers.

Sync or isolated queues. Set the demo environment to QUEUE_CONNECTION=sync so jobs run inline and visibly, or a dedicated queue with a worker that only touches the demo DB. Never let demo jobs land on a production queue.

Neutralize outbound side effects. Set MAIL_MAILER=log, a sandboxed cache store (array or a prefixed Redis DB), and a fake filesystem disk. If the package exposes a "safe drivers" config block, use it; otherwise enforce via the demo .env.

Read-only enforcement at multiple layers. Middleware alone is not enough. Combine:

  • Route-level blocking of destructive verbs (DELETE, bulk POST endpoints).
  • Policy/gate checks that return false in demo context for admin actions.
  • Model-level guards (e.g. an observer that throws on forceDelete).

Session-per-visitor isolation. Give each visitor a fresh demo tenant/user (a pre-seeded demo account or a session-scoped SQLite copy). This is what makes a "playground" feel real without cross-visitor contamination — it's the pattern most demo-mode packages aim for, so check whether this one implements it or expects you to.

Rate limiting and bot protection. Wrap demo routes with throttle: middleware. A public playground is an abuse target; the package's safeguards are not a substitute for edge-level rate limiting.

Feature-flag the demo entry point. Expose a "Try the demo" link only when a config flag is on, so the same codebase serves both the real app and the playground.

Gotchas and Tips

  • Verify the package before trusting the safeguards. Unknown repository, low stars, odd release date. Read src/ — especially the middleware and config — and confirm it's doing what the description claims. Budget for replacing it with ~100 lines of your own middleware if it doesn't fit.
  • Config caching surprises. php artisan config:cache will freeze the demo connection and driver settings. If you switch environments on the same deploy, cache invalidation must be part of the deploy step.
  • Middleware ordering matters. Put the demo middleware before auth/session middleware that might touch the wrong DB, and after StartSession if it needs session-scoped state. A misordered stack can leak the production connection into a demo request.
  • migrate:fresh on a shared file. If multiple requests or workers reset the SQLite file simultaneously, you'll get database is locked errors. Serialize resets with a lock (Cache::lock) or reset on a schedule rather than per request.
  • File uploads. Without a fake disk, uploads land in real storage and accumulate. Configure a demo disk pointing at a temp directory and prune it on the same schedule as the DB reset.
  • External API calls. Demo mode doesn't usually intercept HTTP clients. Add Http::preventStrayRequests() in the demo environment or fake specific endpoints, otherwise visitors can trigger real third-party calls and costs.
  • Debug mode leakage. Ensure APP_DEBUG=false in demo. A stack trace on a public playground exposes config, paths, and sometimes credentials.
  • Telescope/Log viewer. Disable or password-protect debug tooling in the demo environment; these are common accidental data-leak vectors.
  • Session driver. array sessions don't persist across requests; database sessions on the demo connection get wiped by resets. Use a separate session table/connection or accept the reset.
  • Password resets and email verification. With MAIL_MAILER=log, these flows silently "succeed" without sending. Either disable them in demo routes or surface the logged mail in a dev-only inbox UI.
  • Extension point to lean on: a small DemoContext-style service (or whatever the package exposes) injected via the container, so your own guards can ask isDemo() without hard-coding route names. If the package doesn't provide one, add a thin wrapper — it will outlive the package.
  • Upgrade risk. With a single maintainer and few users, pin the version in composer.json and re-read the diff before upgrading. Don't use ^ ranges on a package that controls sandboxing.
  • Testing. Add a feature test that hits a destructive route under the demo middleware and asserts a 403/no-op. That test is your regression guard if the package changes or you swap it out.
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.
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox