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

Streams Platform Laravel Package

anomaly/streams-platform

Streams Platform is a Laravel-based modular application engine for building custom apps and addons. It provides a powerful streams and fields system for defining data structures, a flexible addon and extension architecture, and serves as the foundation of PyroCMS.

View on GitHub
Deep Wiki
Context7

Getting Started

Pin your Laravel version first — Streams is tightly coupled to the framework release it was built for, so check the package's composer.json against your app before anything else.

  1. composer require anomaly/streams-platform on a fresh or compatible Laravel app.
  2. Run the platform installer (php artisan streams:install on most versions; check the README for your tag). This publishes config/streams.php, runs the core migrations, and registers the bundled addons. Make sure the addons/ directory at the project root is writable and that its path is set in config/streams.php.
  3. Run php artisan addon:list (or addon:list equivalent) to confirm the core addons booted. If the list is empty, your addon path or PSR-4 registration is wrong — fix that before writing any code.

Where to look first: read a core addon end to end (the Pages module is the canonical example). Streams is opinionated and the fastest way to learn its conventions is to copy the structure of a module that already ships with the platform: src/, resources/streams/, resources/views/, routes.php, migrations/.

First real use case: scaffold one addon and one stream. php artisan addon:make acme.module.blog (older versions: addon:make), then add resources/streams/posts.php returning a config array with name, slug, namespace, fields, and optional assignments. Follow it with php artisan streams:compile and you have a working table, entry repository, and admin CRUD surface — no hand-written migration or model required.

Implementation Patterns

Addons are the unit of work. Everything — module, extension, plugin, theme, field type — is an addon under addons/{vendor}-{type}-{name} with a matching namespace (Acme\BlogModule\). Keep domain logic inside the addon, not in app/; that is what makes the flat-file model portable.

Streams are schema-as-code. The stream config is the table definition: fields, field type configs, and assignments. Commit these files. Treat the compiler as your migration tool for greenfield streams, and drop to a real migration when you need to alter an existing table.

Query through repositories, not raw SQL. The idiomatic pattern is:

$posts = stream('posts')->getRepository();

$post = $posts->findBySlug('hello-world');
$recent = $posts->where('published', true)->orderBy('created_at', 'desc')->paginate(10);

Criteria methods (where, orderBy, limit, paginate, first, findBy*) keep business logic readable and consistent.

Switch to Eloquent mode when you need relations. Setting 'config' => ['eloquent' => true] (or the equivalent per-stream flag) gives you a real model, eager loading, and relationships — worth it as soon as you're doing joins across assignments. Otherwise stick with the repository for plain reads.

Assignments model relationships between streams. Attach a categories stream to posts via the assignments key and the platform wires up pivot handling and admin UI for you. Use this instead of a bespoke pivot table.

Lean on events for decoupling. Entry lifecycle events (EntryWasCreated, EntryWasUpdated, etc.) are the clean seam for cache invalidation, search indexing, or notifications. Listen or subscribe in the addon's service provider rather than stuffing side effects into controllers.

Reuse standard Laravel inside addons. Routes, migrations, views, policies, form requests, and console commands all work normally; the addon is just a package with a service provider. Don't reinvent them.

Custom field types are the main extension point. Extend the base FieldType class, register the addon type, and you get admin form rendering and validation for free.

Gotchas and Tips

  • Definitions are cached. After editing any stream config you must run php artisan streams:compile (and clear the app cache if things look stale). A surprising number of "why isn't my field showing up" bugs are just an uncompiled definition.
  • The compiler won't alter existing tables. Adding a field to an already-installed stream updates the config but not the database column. Write a migration for anything beyond a fresh install.
  • Naming is load-bearing. Folder name, namespace, composer autoload, and stream slug are all coupled by convention (acme-module-blog ↔ Acme\BlogModule ↔ stream slug posts). A mismatch will silently fail to boot the addon.
  • Slugs are namespaced, not global. If you have two posts streams in different addons, resolve with the fully qualified identifier rather than the bare slug, and verify what actually loaded with the addon list command.
  • Repository vs Eloquent is a real performance trade-off. Repository mode can be slower on complex queries and won't eager-load relations the same way; Eloquent mode pulls in model overhead. Benchmark the list-heavy screens where it matters.
  • Watch for N+1 across assignments. Traverse related streams with eager loading (->with([...])) or a batch criteria call; looping an entry and calling $entry->categories per row is the classic slow path here.
  • Pin the package and Laravel versions together. The platform replaces a lot of framework conventions, so upgrade both deliberately and re-run the compiler and migrations in staging.
  • License is NOASSERTION. Confirm the actual license terms before shipping commercially — the metadata doesn't declare one.
  • Small ecosystem, few dependents. Expect to read the source rather than find answers on Stack Overflow. Keep a local checkout of the package for stack-trace spelunking, and log aggressively — most failures surface in storage/logs/laravel.log as boot/registry errors rather than clean exceptions.
  • Debugging checklist: addon missing → addon:list; fields missing → streams:compile; routes 404 → check the addon's routes.php is loaded by the service provider; stale output → php artisan cache:clear and view:clear.
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.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource