Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Chisel Laravel Package

laravel/chisel

Laravel Chisel provides primitives for starter-kit post-install scripts, letting users opt into features and automatically remove unwanted code. Define a chisel.php with questions and file/PHP mutations to prune sections, imports, interfaces, and config.

View on GitHub
Deep Wiki
Context7

Introduction

Laravel Chisel provides primitives for building post-install scripts that remove unwanted features from Laravel starter kits. Compatible starter kits include a chisel.php script that defines the optional features and the file mutations needed to remove them.

Installation

composer require laravel/chisel

Usage

An example chisel.php script for optional email verification might look like this:

<?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();
        },
    );

Although the questions are defined in the chisel.php file, an external process such as an Artisan command is responsible for rendering them and passing the answers to Chisel's chisel() method. An example Artisan command using Laravel Prompts might look like this:

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');
    }
}

Script Definitions

Method Purpose
Chisel::script($directory) Create a script definition
Question::multiselect(...) Define a multiselect question
questions([...]) Set the script's questions
questions() Retrieve the registered questions
collectAnswers() Begin collecting answers for registered questions
apply($callback) Register an unconditional mutation step
selected($key, $value, then:, else:) Branch on a multiselect answer
selectedAny($key, $values, then:, else:) Branch when any of the given values are selected
selectedAll($key, $values, then:, else:) Branch when all of the given values are selected
chisel($answers) Execute the registered mutations

Answer Collection

collectAnswers() returns a pending answer collector. All methods are fluent and can be called in any order. Answers are resolved when the object is used as an array or toArray() is called. When non-interactive, defaults are used automatically.

Method Purpose
onQuestion($callback) Handle question prompts
interactive($interactive) Configure whether missing answers are prompted interactively
withAnswers($answers) Provide pre-collected answers to skip prompting

File Mutations

file($path) targets a single file. files(...$paths) targets multiple files.

Method Purpose
replace($search, $replace) Replace a string
removeLinesContaining($content) Remove lines containing a string
removeSectionMarkers($tag) Strip section markers, keep the content
removeSection($tag) Remove section markers and the content inside them
delete() Delete the targeted files

PHP File Mutations

php($path) provides AST-based edits. Changes are saved automatically when the object is destroyed.

Method Purpose
removeImport($class) Remove a use statement
removeTrait($trait) Remove a trait usage from the class
removeInterface($interface) Remove an implemented interface

npm

Method Purpose
npm()->install() Install dependencies using the detected package manager
npm()->run($script, ...$arguments) Run a package manager script
npm()->remove(...$packages) Remove packages using the detected package manager

The npm() method detects npm, yarn, pnpm, and bun automatically.

Section Markers

Wrap optional code in comment pairs:

/* @chisel-passkeys */
Fortify::authenticateUsingPasskeys();
/* @end-chisel-passkeys */

JSX files may use block comments with braces:

{
    /* @chisel-passkeys */
}
<PasskeyButton />;
{
    /* @end-chisel-passkeys */
}

removeSectionMarkers('passkeys') keeps the code and removes the markers. removeSection('passkeys') removes both. The chisel- marker prefix is added automatically.

Contributing

Thank you for considering contributing to Chisel! The contribution guide can be found in the Laravel documentation.

Code of Conduct

In order to ensure that the Laravel community is welcoming to all, please review and abide by the Code of Conduct.

Security Vulnerabilities

Please review our security policy on how to report security vulnerabilities.

License

Laravel Chisel is open-sourced software licensed under the MIT license.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky