> ## 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 — 스타터 킷의 포스트 인스톨 스크립트 라이브러리

> laravel/chisel 소개. 스타터 킷에서 불필요한 기능을 제거하기 위한 포스트 인스톨 스크립트용 프리미티브를 제공하는 패키지. v0.1로 2026년 5월에 공개되었습니다.

<Info>
  이 글은 소스 코드 조사에 기반한 정보입니다. v0.1 태그가 붙은 지 얼마 되지 않은 개발 초기 단계의 패키지입니다 (2026년 5월 시점).
</Info>

## Laravel Chisel이란

[Laravel Chisel](https://github.com/laravel/chisel)은 Laravel 스타터 킷에서 불필요한 기능을 제거하기 위한 **포스트 인스톨 스크립트**를 구축하기 위한 프리미티브를 제공하는 패키지입니다.

스타터 킷에는 많은 기능이 미리 포함되어 있지만, 프로젝트에 따라서는 일부 기능이 불필요한 경우가 있습니다. Chisel은 이 문제를, 설치 후에 대화형으로 "필요한 기능만 남기는" 구조를 제공함으로써 해결합니다.

```mermaid theme={null}
graph TD
    A["laravel new로 프로젝트 생성"] --> B["스타터 킷 설치"]
    B --> C["chisel.php 스크립트 실행"]
    C --> D{"사용자 질문<br>(multiselect)"}
    D --> E["선택에 따라<br>불필요한 파일 삭제 · 편집"]
    E --> F["최종 프로젝트 구성"]
```

## 왜 필요한가

Laravel 스타터 킷은 많은 기능을 번들하고 있지만, 모든 프로젝트에서 모든 기능이 필요한 것은 아닙니다. 예를 들어:

* 이메일 인증이 불필요한 프로젝트
* 패스키 인증을 쓰지 않는 프로젝트
* 특정 Livewire 컴포넌트가 불필요한 구성

지금까지는 불필요한 기능을 수동으로 삭제해야 했지만, Chisel을 사용하면 **설치 시의 대화형 프롬프트로 커스터마이징이 완결**됩니다.

## chisel.php 스크립트 정의

Chisel을 사용하는 스타터 킷은 프로젝트 루트에 `chisel.php` 파일을 배치합니다. 이 파일이 "어떤 기능을 옵션으로 할지"를 정의합니다.

```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) {
            // 선택된 경우: 섹션 마커를 제거하고 코드는 남긴다
            $c->files(
                'resources/js/pages/settings/profile.tsx',
                'app/Providers/FortifyServiceProvider.php',
            )->removeSectionMarkers('email-verification');
        },
        else: function (Chisel $c) {
            // 선택되지 않은 경우: 관련 파일과 기능을 삭제
            $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();
        },
    );
```

## 스크립트 정의 메서드

| 메서드                                        | 설명               |
| ------------------------------------------ | ---------------- |
| `Chisel::script($directory)`               | 스크립트 정의 생성       |
| `Question::multiselect(...)`               | 다중 선택 질문 정의      |
| `questions([...])`                         | 스크립트의 질문 설정      |
| `questions()`                              | 등록된 질문 취득        |
| `collectAnswers()`                         | 질문에 대한 응답 수집 시작  |
| `apply($callback)`                         | 무조건적인 변경 스텝 등록   |
| `selected($key, $value, then:, else:)`     | 단일 선택 값으로 분기     |
| `selectedAny($key, $values, then:, else:)` | 값 중 하나라도 선택되면 분기 |
| `selectedAll($key, $values, then:, else:)` | 모든 값이 선택되면 분기    |
| `chisel($answers)`                         | 등록된 변경 실행        |

## 대화형 응답 수집

`collectAnswers()`는 응답 컬렉터를 반환합니다. 모든 메서드는 플루언트하며 임의의 순서로 호출할 수 있습니다. 비대화형 환경에서는 기본값이 자동으로 사용됩니다.

외부의 Artisan 명령이 [Laravel Prompts](https://laravel.com/docs/prompts)를 사용하여 프롬프트를 표시하고, 응답을 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');
    }
}
```

| 메서드                         | 설명                      |
| --------------------------- | ----------------------- |
| `onQuestion($callback)`     | 질문 프롬프트 핸들러 설정          |
| `interactive($interactive)` | 대화형 모드 설정               |
| `withAnswers($answers)`     | 사전 수집된 응답을 제공하여 프롬프트 스킵 |

## 파일 변경

`file($path)`로 단일 파일을, `files(...$paths)`로 여러 파일을 대상으로 삼습니다.

| 메서드                               | 설명                  |
| --------------------------------- | ------------------- |
| `replace($search, $replace)`      | 문자열 치환              |
| `removeLinesContaining($content)` | 지정 문자열을 포함하는 행 삭제   |
| `removeSectionMarkers($tag)`      | 섹션 마커 제거, 콘텐츠는 남김   |
| `removeSection($tag)`             | 섹션 마커와 그 안의 콘텐츠를 삭제 |
| `delete()`                        | 대상 파일 삭제            |

## PHP AST 기반 편집

`php($path)`는 PHP AST를 사용한 편집을 제공합니다. 오브젝트가 파기될 때 변경이 자동 저장됩니다.

PHP AST(추상 구문 트리)의 기초와 `nikic/php-parser` 사용법에 대해서는 [여기](/ko/advanced/php-ast)에서 설명하고 있습니다.

| 메서드                           | 설명                |
| ----------------------------- | ----------------- |
| `removeImport($class)`        | `use` 문 삭제        |
| `removeTrait($trait)`         | 클래스에서 trait 사용 삭제 |
| `removeInterface($interface)` | 구현된 interface 삭제  |

## Section Markers

옵션 코드를 코멘트 쌍으로 감쌉니다.

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

JSX 파일에서는 중괄호(`{}`)를 사용한 블록 코멘트를 사용합니다.

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

* `removeSectionMarkers('passkeys')` — 마커는 삭제하고 코드는 남김
* `removeSection('passkeys')` — 마커도 코드도 모두 삭제

`chisel-` 프리픽스는 자동으로 부가됩니다.

```mermaid theme={null}
graph LR
    A["/* @chisel-feature */<br>코드<br>/* @end-chisel-feature */"] --> B{"사용자가<br>feature를 선택?"}
    B -->|removeSectionMarkers| C["코드만 남김<br>(마커 삭제)"]
    B -->|removeSection| D["마커도 코드도<br>모두 삭제"]
```

## npm 지원

| 메서드                                  | 설명                   |
| ------------------------------------ | -------------------- |
| `npm()->install()`                   | 감지된 패키지 매니저로 의존관계 설치 |
| `npm()->run($script, ...$arguments)` | 패키지 매니저의 스크립트 실행     |
| `npm()->remove(...$packages)`        | 감지된 패키지 매니저로 패키지 삭제  |

`npm()` 메서드는 npm · yarn · pnpm · bun을 자동 감지합니다.

## 현재의 개발 상황

* **GitHub 리포지토리**: [laravel/chisel](https://github.com/laravel/chisel)
* **릴리스**: v0.1 (2026년 5월 공개)
* **개발 기간**: 3개월간의 비공개 개발을 거쳐 공개

Chisel은 최종 사용자가 Laravel 앱에 직접 설치하는 패키지가 아니라, **스타터 킷이 내부적으로 사용하는 라이브러리**입니다. 장래에는 Laravel의 공식 스타터 킷이 Chisel을 활용한 포스트 인스톨 스크립트를 제공하는 것이 기대됩니다.

<Card title="laravel/chisel 리포지토리" icon="github" href="https://github.com/laravel/chisel">
  소스 코드와 최신 API 레퍼런스는 이곳에서 확인하실 수 있습니다.
</Card>

<Card title="Laravel 스타터 킷 공식 문서" icon="book-open" href="https://laravel.com/docs/starter-kits">
  스타터 킷 자체의 사용법에 대해서는 공식 문서를 참고하세요.
</Card>


## Related topics

- [Laravel 스타터 킷 만드는 법](/ko/advanced/starter-kit-creation.md)
- [Laravel MCP](/ko/mcp.md)
- [설치](/ko/installation.md)
- [PHP AST](/ko/advanced/php-ast.md)
- [Laravel Package Skeleton — 공식 패키지용 스타터 템플릿](/ko/blog/package-skeleton-introduction.md)
