andrecorugda/synapse
Synapse is a Laravel/PHP package that offers a simple, expressive API for wiring together the moving parts of your application. It is lightweight, follows Laravel conventions, and can be installed and configured quickly in existing projects.
Minimal path from install to a first working screen:
Install and wire the package
composer require andrecorugda/synapse
php artisan vendor:publish --provider="Andrecorugda\\Synapse\\SynapseServiceProvider"
php artisan migrate
Run vendor:publish --tag=synapse-config explicitly if the provider tag name differs — check the publishes() block first, since the package ships with several groups (config, migrations, assets, maybe panel).
Read these files first, in this order
config/synapse.php — panel toggle, auth guard name, route prefix, table prefix, flow engine and external datasource settings. Everything you'll need to change lives here.database/migrations/* — because tables are prefixed (synapse_*), you need to know the shape before you write joins or reports against collections.routes/ — the panel and REST routes defer to yours; confirm the prefixes before adding any of your own, or you'll shadow each other.src/Blocks/BlockVocabulary.php (or equivalent) — the canonical list of block keys. Treat this as the public palette registry; it's your extension point for custom blocks.First use case worth trying
End-user auth
Decide early whether the package's own guard (synapse or configured guard) is what you want for your end-users, or whether you'll bridge it to your app's users. It's a separate guard on purpose; retrofitting is painful.
Schema-first app building Start with the collection definition (typed schema) and let the REST API fall out. Do not build pages against ad-hoc models — that defeats the point. Use the collection types (text, number, date, relation, JSON, etc.) so the auto-generated validation and API stay consistent.
Two audiences, two guards — keep them separate
web/admin) live in your tables.config/synapse.php, and bridge to your IdP via the documented external auth hook rather than rewriting the guard.GrapesJS block extension
To add a custom block, register it against the block vocabulary and provide a preview icon. The icon goes through Icons::for($key) and must be a full self-contained <svg viewBox="0 0 256 256"> with the color set in an inline style, not fill=. See Gotchas below; this is the single most common silent failure.
// pattern — mirror the shipped blocks
Icons::GLYPHS['kpi_card'] = '<svg style="width:26px;height:26px;fill:#10B981" viewBox="0 0 256 256">…</svg>';
Flows (n8n-style engine) Model flows as: trigger → nodes → output. Use the built-in node types for HTTP, branching, and collection writes. For anything external, prefer a flow node over a controller — it's inspectable and re-runnable, and the engine handles retries/serialization. Keep flow state out of your controllers; let flows own their own state table (also prefixed).
External data sources
Wire external sources through the package's datasource layer rather than raw Http:: calls. You get credential storage, test-connection buttons, and consistent error handling for free. Map external fields into local collection fields at the datasource layer, not inside page templates — that keeps templates portable if the source changes.
Runs alongside, doesn't take over
routes/web.php; the package is designed to defer. If a path needs to be yours, add it before loading the Synapse routes, or exclude it via config./app prefix to avoid colliding with admin.synapse_* without touching your app's data.AI as accelerator, not dependency Treat AI-generated pages/blocks/flows as scaffolding you commit and then edit by hand. Don't route runtime behavior through the AI features — they're optional and the package should function fully with them off.
SVG icons will silently render gray
GrapesJS's block-manager stylesheet applies svg { fill: … }, and CSS beats the SVG fill presentation attribute. Always put color in the inline style:
<svg style="width:26px;height:26px;fill:#6366F1" viewBox="0 0 256 256">…</svg>
Verify in-browser with getComputedStyle(svg).fill — if it's gray, the color is in the wrong place. Don't trust the markup.
Every block key needs its own icon
When adding blocks, diff your additions against BlockVocabulary::all(). Missing keys fall back to a generic square, which makes the palette look broken. Regenerating the icon set is scripted (Phosphor duotone), and the script logs 404s to glyphs.miss — check that file, don't assume success.
Opt-in panel means routes may be missing
If /app (or whatever prefix) 404s, the panel provider isn't registered or the toggle in config is off. This is intentional (safe default) but trips up first-run setup.
Guard confusion is the #1 support ticket
Two guards means two auth()->guard(...) calls. Redirects, middleware, and @auth all default to web. If end-users get logged out on the panel, you've almost certainly missed a guard name in a middleware or a policy. Audit every auth() call and be explicit.
Migrations and prefixed tables
The package writes to synapse_*. If you run migrate:fresh on shared environments you'll wipe the built app too. Keep package migrations in their own publishing group and treat synapse_* as production data once you go live — snapshot before any migrate:refresh.
Flow debugging n8n-style engines hide retries and serialization. When a flow misbehaves, check the flow-run log table before reading code — most issues are auth/config at the node level, not logic. Add a no-op "debug" node at the point of failure and inspect its payload through the panel.
Low signal from the community 12 stars, zero dependents. That's fine for a self-hosted tool but means:
BlockVocabulary, config/synapse.php, and the service provider are the three files that tell you 80% of the truth.php artisan tinker --execute="echo collect(BlockVocabulary::all())->map(fn(\$b)=>\$b->key)->implode(' ');" to enumerate blocks quickly when the README disagrees with reality.Extension points to lean on (and protect)
Custom blocks, custom flow nodes, custom datasources — these are the stable seams. Wrap your own classes around them (e.g., App\Synapse\Blocks\…) so a package upgrade is a rebase of a thin layer rather than a search-and-replace. Avoid editing files under vendor/; if you must patch, log it and open an upstream issue.
Assets and caching
Filament panel assets and GrapesJS bundles are published. If you edit them, php artisan filament:assets (or the package's equivalent) and a cache clear are required, and stale public/ builds look identical to a code bug. When in doubt, hard-refresh and check DevTools getComputedStyle on any suspicious icon.
How can I help you explore Laravel packages today?