Installation
composer require flexpik/filament-studio
php artisan vendor:publish --tag="filament-studio-migrations"
php artisan migrate
Register Plugin
Add to your app/Providers/Filament/AdminPanelProvider.php:
public function panel(Panel $panel): Panel
{
return $panel->plugins([
FilamentStudioPlugin::make(),
]);
}
First Collection Navigate to Studio > Collections in Filament admin panel. Click "Create Collection" and define:
Text, Select, Date)First Record After saving the collection, visit its "Records" tab to create/edit records via the auto-generated CRUD interface.
/admin/studio/collections/admin/studio/collections/{slug}/fields/admin/studio/collections/{slug}/recordsdocs/field-types.md (for field customization)name (Text)price (Decimal)sku (Slug)categories (Multi-Select)images (Repeater with Image fields)sequenceDiagram
participant Admin
participant Studio
participant App
Admin->>Studio: Create "Events" collection
Admin->>Studio: Add fields (title, date, location, attendees)
Studio->>App: Auto-generates CRUD, API, and Filament resources
App->>Studio: Extend via hooks (e.g., modify form schema)
// Modify form schema for a specific collection
FilamentStudioPlugin::modifyFormSchema(
fn (array $schema, $collection) => {
if ($collection->slug === 'products') {
$schema[] = TextInput::make('custom_field')->columnSpanFull();
}
return $schema;
}
);
// Add custom validation
FilamentStudioPlugin::afterFieldAdded(
fn ($field) => {
if ($field->type === 'email') {
$field->validationRules = ['email', 'required'];
}
}
);
amount, date, and product_id fields.datesum(amount)product_id = "123"# Get API key
curl -X POST http://your-app.test/api/studio/api-keys \
-H "Authorization: Bearer {FILAMENT_ADMIN_TOKEN}" \
-d '{"name":"Frontend App"}'
# Fetch records
curl -X GET http://your-app.test/api/studio/collections/products/records \
-H "Authorization: Bearer {API_KEY}"
// In a tenant-aware context (e.g., middleware)
$tenant = Tenant::find($request->tenantId);
$records = Studio::collection('products')
->forTenant($tenant)
->getRecords();
use Flexpik\FilamentStudio\Resources\StudioResource;
public static function getRelations(): array
{
return [
StudioResource::make('products')
->query(fn (Builder $query) => $query->where('tenant_id', auth()->user()->tenant_id))
->titleColumn('name'),
];
}
public function run(): void
{
$collection = Studio::createCollection([
'slug' => 'users',
'name' => 'Users',
'fields' => [
[
'type' => 'text',
'name' => 'name',
'settings' => ['max_length' => 255],
],
[
'type' => 'email',
'name' => 'email',
'settings' => ['unique' => true],
],
],
]);
}
FilamentStudioPlugin::make()
->fieldTypes([
'rating' => \App\FieldTypes\RatingFieldType::class,
'currency' => \App\FieldTypes\CurrencyFieldType::class,
]);
FilamentStudioPlugin::modifyFormSchema(
fn (array $schema, $collection) => {
if ($collection->slug === 'subscriptions') {
$schema[] = TextInput::make('trial_end_date')
->visible(fn () => auth()->user()->hasRole('admin'));
}
return $schema;
}
);
# Start MCP server
php artisan mcp:start studio
# Connect via stdio (e.g., in Cursor or Claude)
{
"mcpServers": {
"studio": {
"type": "stdio",
"command": "php",
"args": ["artisan", "mcp:start", "studio"],
"env": {
"STUDIO_API_KEY": "your-secure-key",
"STUDIO_MCP_ENABLED": "true"
}
}
}
}
Issue: EAV storage can impact query performance for large datasets due to denormalized structure.
with() to eager-load related fields:
$records = Studio::collection('products')
->with(['images', 'categories'])
->getRecords();
Tip: Monitor studio_values table size; optimize with indexes on record_id and field_name.
eav_cast (e.g., from Integer to Text) may corrupt existing data.
Schema::table('studio_values', function (Blueprint $table) {
$table->text('value_text')->nullable()->after('value');
});
FilamentStudioPlugin::afterFieldUpdated() to handleHow can I help you explore Laravel packages today?