exceedone/exment
Exment is an open-source, self-hosted, Laravel-based no-code/low-code platform for building custom business apps, databases, and workflows. It provides Excel-like tables, forms, permissions, dashboards, and automation, enabling teams to manage data and processes without coding.
First, reset your expectations: Exment is not a library you require into an existing app — it is a Laravel application distributed as a package. The exceedone/exment Composer entry installs routes, migrations, admin screens, auth, assets, and a plugin runtime on top of a Laravel skeleton. "Dependents: 0" on the repo is the tell: almost nobody consumes it as a dependency of something else; they install it as the thing. Plan accordingly.
Pin to 6.2.15 or later from day one. The 6.2.15 release is a security release: it fixes eight JVNs covering SQL injection, two directory traversal issues, improper authentication, improper access restriction, and three cross-site scripting issues. If you are evaluating Exment on an older 6.x, you are evaluating a version with known, publicly catalogued vulnerabilities. Check composer show exceedone/exment before you assess anything else.
Minimal path:
composer create-project laravel/laravel exment-app # check Exment's supported Laravel major first
cd exment-app
composer require exceedone/exment:^6.2.15 # do not float below the patched release
php artisan exment:install
php artisan serve
Then set APP_URL, database credentials, and mail in .env before installing, and create the initial admin user when prompted. Log in at /admin.
Where to look first, in this order:
config/exment.php — the single most informative file in the package. It tells you the URL prefix, auth guard, file storage paths, and feature flags.plugins/ and the sample plugins shipped in the repo — this is the officially blessed extension mechanism and the best-documented one.php artisan list | grep exment — confirm the exact install/update/publish commands for your pinned version; they drift between releases.First use case that pays for itself: build one small custom table (e.g. "Customers") with 4–5 columns, one custom view with a filter, then create an API token in System settings → API and round-trip a record from curl:
curl -H "Authorization: Bearer $TOKEN" -H "Accept: application/json" \
https://your-host/admin/api/... # endpoint shape is version-specific; read the API docs screen
Doing this on day one teaches the three things that matter: the custom-table data model, the permission model (your token inherits the user's role), and that the API is the sanctioned integration boundary rather than direct DB access.
Configure before you code. Custom tables, columns, views, data rules, and workflows cover the large majority of "we need a system for X" requests without a single line of PHP. A developer who reaches for migrations and controllers first will fight the framework the whole way. The winning posture is: model it in the admin UI, then write code only for what the UI genuinely cannot express.
Plugins are the unit of extension. Everything custom lives in plugins/{vendor}/{name}/ with a config.json (name, version, description, author, supported Exment version) plus a service provider that can register routes, views, menu items, and settings screens. Install/enable through the admin plugin screen. Copy the structure from a bundled sample plugin verbatim rather than inventing a layout — the config.json keys and version-compat field are load-bearing, and a mismatched version silently refuses to activate.
Use plugins for side effects, data rules for derived values. Simple calculations, defaults, and validation belong in column-level "calculated" settings and data rules. Anything that calls an external API, sends a notification, or mutates other tables on save belongs in a plugin hooking the custom-value lifecycle. Splitting these correctly is the difference between a maintainable instance and a pile of hooks.
API-first for integration and ETL. Treat the REST API (token auth) as the contract with every external system: nightly syncs, spreadsheet uploads from other departments, pushing records into a BI tool. For idempotent syncs, designate a unique-key column (customer code, ticket number) and upsert on that key rather than blind-create. Paginate explicitly and filter server-side — pulling an entire custom table to filter in your script is the most common self-inflicted performance wound.
Views are the UI layer, not an afterthought. Different roles want different slices of the same table. Define a custom view per role/use case (filter + visible columns + sort) instead of building custom pages. Views also carry the summary/aggregate display most stakeholders actually want, and they cost nothing to change later. Note that 6.2.15 also fixes a display bug in custom-view data display conditions — if you built views with conditions on an older patch, re-check them after upgrading.
Workflow + notification rather than a hand-rolled state machine. For approvals and status transitions, use the workflow feature and a status column. Reimplementing approval logic in a plugin means reimplementing the audit trail, the notification fan-out, and the permission checks too.
Treat templates as your migration story. Export custom table/column definitions as a template and commit the JSON to git. Import into staging and production. This is the closest Exment gets to php artisan migrate for structure, and it is the only sane way to keep environments in sync. Pair it with CSV import/export (with explicit column mapping) for data seeding and for letting business users self-serve bulk loads.
Match the permission model early. Exment's authorization is role-based, table-granular, and organization-aware. Decide the role matrix before building screens: retrofitting row-level and organization scoping onto a live instance with real data is painful. And remember the API enforces the same rules — a token is not a superuser key.
Schedule patch upgrades like dependency security updates. 6.2.15 is a pure security/bugfix release on the 6.2 line — no breaking changes, no migration work, safe to take quickly. Make "check for a new 6.2.x" a recurring task; the vulnerability classes fixed here (SQLi, traversal, auth bypass) are exactly the ones you do not want sitting on an internet-facing instance.
/admin routes, auth guard, middleware, and views. Bolting it onto a production app that already has login and an admin panel is a multi-day fight. Prefer a standalone install, or run it on its own subdomain with a shared database if you must integrate.laravel/framework. Your upgrade cadence becomes Exment's cadence. Check the constraint before promising a security patch timeline — and note that a slow Exment release cadence directly gates your ability to respond to Laravel CVEs.vendor/. Any fix applied there disappears on the next composer update. Everything goes in a plugin or config/exment.php. This is the single discipline that makes upgrades survivable — and with security patches now arriving on the 6.2.x line, you will be running composer update more often than you'd like.vendor/ for those areas will conflict or be silently reverted. Re-express your workaround as a plugin/config change before upgrading.storage/logs/laravel.log plus a real stack trace via APP_DEBUG. Exment's own exception handling occasionally degrades a fatal into a generic error screen, so when the UI says nothing useful, the log is the only source of truth. Turn APP_DEBUG off again in production — it is not a long-term diagnostic posture on an app that has shipped auth-related CVEs.How can I help you explore Laravel packages today?