> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Laravel Chisel – Post-Install-Skript-Bibliothek für Starterkits

> Vorstellung von laravel/chisel. Ein Paket, das Primitive für Post-Install-Skripte bereitstellt, mit denen sich nicht benötigte Funktionen aus einem Starterkit entfernen lassen. Im Mai 2026 als v0.1 veröffentlicht.

<Info>
  Dieser Artikel basiert auf einer Analyse des Quellcodes. Das Paket befindet sich in einem frühen Entwicklungsstadium und trägt gerade erst das Tag v0.1 (Stand: Mai 2026).
</Info>

## Was ist Laravel Chisel?

[Laravel Chisel](https://github.com/laravel/chisel) ist ein Paket, das Primitive bereitstellt, um **Post-Install-Skripte** zu bauen, welche nicht benötigte Funktionen aus einem Laravel-Starterkit entfernen.

Starterkits enthalten viele vorgefertigte Funktionen; je nach Projekt sind aber nur ein Teil davon nötig. Chisel löst dieses Problem, indem es einen Mechanismus bereitstellt, mit dem sich nach der Installation interaktiv „nur die benötigten Funktionen behalten" lassen.

```mermaid theme={null}
graph TD
    A["Projekt mit laravel new anlegen"] --> B["Starterkit installieren"]
    B --> C["Skript chisel.php ausführen"]
    C --> D{"Fragen an den Nutzer<br>(multiselect)"}
    D --> E["Nicht benötigte Dateien<br>je nach Auswahl entfernen/bearbeiten"]
    E --> F["Endgültige Projektkonfiguration"]
```

## Warum wird das benötigt?

Laravel-Starterkits bündeln viele Funktionen, aber nicht in jedem Projekt sind alle davon nötig. Beispiele:

* Projekte, die keine E-Mail-Verifizierung brauchen
* Projekte, die keine Passkey-Authentifizierung nutzen
* Konstellationen, in denen bestimmte Livewire-Komponenten nicht gebraucht werden

Bisher musste man nicht benötigte Features manuell entfernen. Mit Chisel lässt sich die Anpassung **direkt bei der Installation über interaktive Prompts abschließen**.

## Definition des chisel.php-Skripts

Ein Starterkit, das Chisel nutzt, legt eine Datei `chisel.php` im Projekt-Root an. Darin wird definiert, „welche Funktionen optional sein sollen".

```php theme={null}
<?php

require getenv('LARAVEL_INSTALLER_AUTOLOADER');

use Laravel\Chisel\Chisel;
use Laravel\Chisel\Question;

return Chisel::script(dirname(__DIR__))
    ->questions([
        Question::multiselect(
            name: 'auth_features',
            label: 'Which authentication features would you like to enable?',
            options: [
                'email-verification' => 'Email verification',
            ],
            hint: 'Use space to select, enter to confirm.',
        ),
    ])
    ->selected('auth_features', 'email-verification',
        then: function (Chisel $c) {
            // Bei Auswahl: Section-Marker entfernen, Code beibehalten
            $c->files(
                'resources/js/pages/settings/profile.tsx',
                'app/Providers/FortifyServiceProvider.php',
            )->removeSectionMarkers('email-verification');
        },
        else: function (Chisel $c) {
            // Wenn nicht gewählt: zugehörige Dateien und Funktionen entfernen
            $c->php('app/Models/User.php')
                ->removeImport('Illuminate\Contracts\Auth\MustVerifyEmail')
                ->removeInterface('MustVerifyEmail');

            $c->file('config/fortify.php')->removeLinesContaining('Features::emailVerification()');

            $c->files(
                'app/Providers/FortifyServiceProvider.php',
                'resources/js/pages/settings/profile.tsx',
            )->removeSection('email-verification');

            $c->files(
                'resources/js/components/email-verification-notice.tsx',
                'resources/js/pages/auth/verify-email.tsx',
                'tests/Feature/Auth/EmailVerificationTest.php',
                'tests/Feature/Auth/VerificationNotificationTest.php',
            )->delete();
        },
    );
```

## Methoden zur Skript-Definition

| Methode                                    | Beschreibung                                       |
| ------------------------------------------ | -------------------------------------------------- |
| `Chisel::script($directory)`               | Legt eine Skript-Definition an                     |
| `Question::multiselect(...)`               | Definiert eine Mehrfachauswahl-Frage               |
| `questions([...])`                         | Setzt die Fragen des Skripts                       |
| `questions()`                              | Gibt die registrierten Fragen zurück               |
| `collectAnswers()`                         | Startet das Einsammeln der Antworten               |
| `apply($callback)`                         | Registriert einen bedingungslosen Mutationsschritt |
| `selected($key, $value, then:, else:)`     | Verzweigt bei einem einzelnen ausgewählten Wert    |
| `selectedAny($key, $values, then:, else:)` | Verzweigt, wenn einer der Werte ausgewählt wurde   |
| `selectedAll($key, $values, then:, else:)` | Verzweigt, wenn alle Werte ausgewählt wurden       |
| `chisel($answers)`                         | Führt die registrierten Mutationen aus             |

## Interaktives Einsammeln der Antworten

`collectAnswers()` gibt einen Answer-Collector zurück. Alle Methoden sind fluent und in beliebiger Reihenfolge aufrufbar. In nicht-interaktiven Umgebungen werden automatisch die Standardwerte verwendet.

Ein externes Artisan-Kommando zeigt Prompts mithilfe von [Laravel Prompts](https://laravel.com/docs/prompts) an und übergibt die Antworten an Chisel.

```php theme={null}
use Illuminate\Console\Command;
use Laravel\Chisel\Chisel;
use Laravel\Chisel\Question;
use RuntimeException;

use function Laravel\Prompts\multiselect;

class InstallFeatures extends Command
{
    protected $signature = 'install:features
        {--answers= : JSON string of answers to skip interactive prompts}';

    public function handle(): void
    {
        $script = require base_path('chisel.php');

        $providedAnswers = $this->option('answers') === null
            ? []
            : json_decode((string) $this->option('answers'), true, 512, JSON_THROW_ON_ERROR);

        $answers = $script
            ->collectAnswers()
            ->onQuestion(fn (Question $question) => match ($question->type) {
                'multiselect' => multiselect(
                    label: $question->label,
                    options: $question->options,
                    default: $question->default ?? [],
                    required: $question->required,
                    hint: $question->hint,
                ),
                default => throw new RuntimeException("Unsupported question type [{$question->type}]."),
            })
            ->interactive($this->input->isInteractive())
            ->withAnswers($providedAnswers);

        $script->chisel($answers);

        $chisel = Chisel::in(base_path());

        $chisel->npm()->install();
        $chisel->npm()->run('build');
    }
}
```

| Methode                     | Beschreibung                                               |
| --------------------------- | ---------------------------------------------------------- |
| `onQuestion($callback)`     | Legt den Handler für Frage-Prompts fest                    |
| `interactive($interactive)` | Setzt den interaktiven Modus                               |
| `withAnswers($answers)`     | Liefert vorab gesammelte Antworten und überspringt Prompts |

## Datei-Mutationen

Mit `file($path)` wird eine einzelne Datei, mit `files(...$paths)` mehrere Dateien angesprochen.

| Methode                           | Beschreibung                                        |
| --------------------------------- | --------------------------------------------------- |
| `replace($search, $replace)`      | Zeichenkette ersetzen                               |
| `removeLinesContaining($content)` | Zeilen mit der angegebenen Zeichenkette entfernen   |
| `removeSectionMarkers($tag)`      | Section-Marker entfernen, Inhalt beibehalten        |
| `removeSection($tag)`             | Section-Marker und den enthaltenen Inhalt entfernen |
| `delete()`                        | Zieldatei löschen                                   |

## Bearbeitung auf Basis des PHP-AST

`php($path)` ermöglicht das Bearbeiten über den PHP-AST. Änderungen werden beim Zerstören des Objekts automatisch gespeichert.

Die Grundlagen des PHP-AST (Abstract Syntax Tree) und die Nutzung von `nikic/php-parser` sind [hier](/de/advanced/php-ast) erläutert.

| Methode                       | Beschreibung                                    |
| ----------------------------- | ----------------------------------------------- |
| `removeImport($class)`        | `use`-Statement entfernen                       |
| `removeTrait($trait)`         | Nutzung eines Traits aus einer Klasse entfernen |
| `removeInterface($interface)` | Implementiertes Interface entfernen             |

## Section Marker

Optionaler Code wird von Kommentar-Paaren umschlossen.

```php theme={null}
/* @chisel-passkeys */
Fortify::authenticateUsingPasskeys();
/* @end-chisel-passkeys */
```

In JSX-Dateien werden Block-Kommentare mit geschweiften Klammern (`{}`) verwendet.

```tsx theme={null}
{
    /* @chisel-passkeys */
}
<PasskeyButton />;
{
    /* @end-chisel-passkeys */
}
```

* `removeSectionMarkers('passkeys')` – entfernt die Marker, der Code bleibt erhalten
* `removeSection('passkeys')` – entfernt sowohl Marker als auch Code

Das Präfix `chisel-` wird automatisch ergänzt.

```mermaid theme={null}
graph LR
    A["/* @chisel-feature */<br>Code<br>/* @end-chisel-feature */"] --> B{"Feature vom<br>Nutzer gewählt?"}
    B -->|removeSectionMarkers| C["Nur Code beibehalten<br>(Marker entfernen)"]
    B -->|removeSection| D["Marker und Code<br>vollständig entfernen"]
```

## npm-Unterstützung

| Methode                              | Beschreibung                                               |
| ------------------------------------ | ---------------------------------------------------------- |
| `npm()->install()`                   | Abhängigkeiten mit dem erkannten Paketmanager installieren |
| `npm()->run($script, ...$arguments)` | Ein Skript des Paketmanagers ausführen                     |
| `npm()->remove(...$packages)`        | Pakete mit dem erkannten Paketmanager entfernen            |

Die Methode `npm()` erkennt npm, yarn, pnpm und bun automatisch.

## Aktueller Entwicklungsstand

* **GitHub-Repository**: [laravel/chisel](https://github.com/laravel/chisel)
* **Release**: v0.1 (veröffentlicht Mai 2026)
* **Entwicklungszeit**: nach dreimonatiger nicht-öffentlicher Entwicklung veröffentlicht

Chisel ist kein Paket, das Endnutzer direkt in einer Laravel-Anwendung installieren, sondern **eine Bibliothek, die intern von Starterkits verwendet wird**. Perspektivisch ist zu erwarten, dass die offiziellen Laravel-Starterkits Post-Install-Skripte auf Basis von Chisel anbieten.

<Card title="Repository laravel/chisel" icon="github" href="https://github.com/laravel/chisel">
  Quellcode und aktuelle API-Referenz finden Sie hier.
</Card>

<Card title="Offizielle Dokumentation der Laravel-Starterkits" icon="book-open" href="https://laravel.com/docs/starter-kits">
  Zur Nutzung der Starterkits selbst konsultieren Sie bitte die offizielle Dokumentation.
</Card>


## Related topics

- [React – Einstieg mit Inertia × Laravel](/de/blog/react-introduction.md)
- [Laravel Maestro – Orchestrator für die Entwicklung von Starterkits](/de/blog/maestro-introduction.md)
- [PHP, Composer und Node.js mit WSL installieren (Windows)](/de/blog/windows-setup.md)
- [VOICEVOX Core für PHP](/de/packages/voicevox-core-php/index.md)
- [PHP AST](/de/advanced/php-ast.md)
