> ## 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 — Biblioteca de scripts de post-instalación para starter kits

> Presentación de laravel/chisel. Paquete que ofrece primitivas para scripts de post-instalación destinados a eliminar funcionalidades innecesarias de los starter kits. Publicado en mayo de 2026 como v0.1.

<Info>
  Este artículo se basa en la investigación del código fuente. Es un paquete en fase inicial de desarrollo, recién etiquetado como v0.1 (a fecha de mayo de 2026).
</Info>

## ¿Qué es Laravel Chisel?

[Laravel Chisel](https://github.com/laravel/chisel) es un paquete que proporciona primitivas para construir **scripts de post-instalación** que eliminan funcionalidades innecesarias de los starter kits de Laravel.

Los starter kits incluyen muchas funciones predefinidas, pero según el proyecto puede haber funciones que no se necesitan. Chisel resuelve este problema ofreciendo un mecanismo que, tras la instalación, permite de forma interactiva "conservar solo las funciones necesarias".

```mermaid theme={null}
graph TD
    A["Crear proyecto con laravel new"] --> B["Instalación del starter kit"]
    B --> C["Ejecución del script chisel.php"]
    C --> D{"Pregunta al usuario<br>(multiselect)"}
    D --> E["Eliminar/editar los archivos<br>innecesarios según la selección"]
    E --> F["Estructura final del proyecto"]
```

## Por qué es necesario

Los starter kits de Laravel empaquetan muchas funcionalidades, pero no todos los proyectos necesitan todas ellas. Por ejemplo:

* Proyectos que no requieren verificación por email
* Proyectos que no usan autenticación con passkeys
* Configuraciones que no necesitan ciertos componentes de Livewire

Antes había que eliminar manualmente las funciones innecesarias, pero con Chiel **la personalización se completa mediante prompts interactivos en el momento de la instalación**.

## Definición del script chisel.php

Los starter kits que usan Chisel colocan un archivo `chisel.php` en la raíz del proyecto. Ese archivo define "qué funcionalidades son opcionales".

```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) {
            // Si se selecciona: elimina los marcadores de sección y conserva el código
            $c->files(
                'resources/js/pages/settings/profile.tsx',
                'app/Providers/FortifyServiceProvider.php',
            )->removeSectionMarkers('email-verification');
        },
        else: function (Chisel $c) {
            // Si no se selecciona: elimina los archivos y funcionalidades relacionados
            $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();
        },
    );
```

## Métodos de definición del script

| Método                                     | Descripción                                         |
| ------------------------------------------ | --------------------------------------------------- |
| `Chisel::script($directory)`               | Crea la definición de script                        |
| `Question::multiselect(...)`               | Define una pregunta de selección múltiple           |
| `questions([...])`                         | Configura las preguntas del script                  |
| `questions()`                              | Obtiene las preguntas registradas                   |
| `collectAnswers()`                         | Inicia la recolección de respuestas a las preguntas |
| `apply($callback)`                         | Registra un paso de mutación incondicional          |
| `selected($key, $value, then:, else:)`     | Ramifica según un único valor seleccionado          |
| `selectedAny($key, $values, then:, else:)` | Ramifica si se selecciona alguno de los valores     |
| `selectedAll($key, $values, then:, else:)` | Ramifica si se seleccionan todos los valores        |
| `chisel($answers)`                         | Ejecuta las mutaciones registradas                  |

## Recolección interactiva de respuestas

`collectAnswers()` devuelve un recolector de respuestas. Todos los métodos son fluidos y pueden llamarse en cualquier orden. En entornos no interactivos se usan automáticamente valores por defecto.

Un comando Artisan externo muestra el prompt usando [Laravel Prompts](https://laravel.com/docs/prompts) y pasa las respuestas a 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');
    }
}
```

| Método                      | Descripción                                                        |
| --------------------------- | ------------------------------------------------------------------ |
| `onQuestion($callback)`     | Establece el handler del prompt de la pregunta                     |
| `interactive($interactive)` | Configura el modo interactivo                                      |
| `withAnswers($answers)`     | Aporta respuestas recolectadas de antemano para saltarse el prompt |

## Mutación de archivos

Con `file($path)` se apunta a un único archivo, y con `files(...$paths)` a varios archivos.

| Método                            | Descripción                                               |
| --------------------------------- | --------------------------------------------------------- |
| `replace($search, $replace)`      | Sustituye una cadena                                      |
| `removeLinesContaining($content)` | Elimina las líneas que contienen la cadena especificada   |
| `removeSectionMarkers($tag)`      | Elimina los marcadores de sección y conserva el contenido |
| `removeSection($tag)`             | Elimina los marcadores de sección y su contenido          |
| `delete()`                        | Elimina el archivo objetivo                               |

## Edición basada en AST de PHP

`php($path)` ofrece edición basada en el AST de PHP. Cuando el objeto se descarta, los cambios se guardan automáticamente.

Los fundamentos del AST (árbol sintáctico abstracto) de PHP y el uso de `nikic/php-parser` se explican [aquí](/es/advanced/php-ast).

| Método                        | Descripción                             |
| ----------------------------- | --------------------------------------- |
| `removeImport($class)`        | Elimina una sentencia `use`             |
| `removeTrait($trait)`         | Elimina el uso de un trait de una clase |
| `removeInterface($interface)` | Elimina una interfaz implementada       |

## Section Markers

Se envuelve el código opcional con pares de comentarios.

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

En archivos JSX se usan comentarios de bloque con llaves (`{}`).

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

* `removeSectionMarkers('passkeys')` — elimina los marcadores y deja el código
* `removeSection('passkeys')` — elimina tanto los marcadores como el código

El prefijo `chisel-` se añade automáticamente.

```mermaid theme={null}
graph LR
    A["/* @chisel-feature */<br>código<br>/* @end-chisel-feature */"] --> B{"¿El usuario<br>seleccionó feature?"}
    B -->|removeSectionMarkers| C["Deja solo el código<br>(elimina los marcadores)"]
    B -->|removeSection| D["Elimina marcadores<br>y código completos"]
```

## Soporte de npm

| Método                               | Descripción                                                  |
| ------------------------------------ | ------------------------------------------------------------ |
| `npm()->install()`                   | Instala las dependencias con el gestor de paquetes detectado |
| `npm()->run($script, ...$arguments)` | Ejecuta un script del gestor de paquetes                     |
| `npm()->remove(...$packages)`        | Elimina paquetes con el gestor de paquetes detectado         |

El método `npm()` detecta automáticamente npm, yarn, pnpm y bun.

## Estado actual de desarrollo

* **Repositorio de GitHub**: [laravel/chisel](https://github.com/laravel/chisel)
* **Release**: v0.1 (publicado en mayo de 2026)
* **Duración del desarrollo**: se publicó tras 3 meses de desarrollo privado

Chisel no es un paquete que los usuarios finales instalen directamente en sus aplicaciones Laravel, sino **una biblioteca que los starter kits usan internamente**. Se espera que en el futuro los starter kits oficiales de Laravel proporcionen scripts de post-instalación basados en Chisel.

<Card title="Repositorio laravel/chisel" icon="github" href="https://github.com/laravel/chisel">
  Aquí puedes consultar el código fuente y la referencia de API más reciente.
</Card>

<Card title="Documentación oficial de starter kits de Laravel" icon="book-open" href="https://laravel.com/docs/starter-kits">
  Para el uso de los propios starter kits, consulta la documentación oficial.
</Card>


## Related topics

- [Instalación](/es/installation.md)
- [Introducción a Svelte — Fundamentos para usarlo con Inertia × Laravel](/es/blog/svelte-introduction.md)
- [Introducción a React — Fundamentos para usarlo con Inertia × Laravel](/es/blog/react-introduction.md)
- [Starter kits](/es/starter-kits.md)
- [Cómo crear un starter kit de Laravel](/es/advanced/starter-kit-creation.md)
