Laravel Zero Get started
Version 12 is out — built on Laravel 12

It's a wonderful day for shipping a CLI.

Laravel Zero is a micro-framework for console applications. All the elegance of Laravel, none of the web — and a single binary at the end of it.

$ composer create-project laravel-zero/laravel-zero my-cli

php my-cli release --patch

◐ Bumping version ................ 1.4.2

◐ Compiling PHAR ................. 4.1 MB

◐ Signing artifact ............... OK

DONE Released in 3.02s — go make a coffee. ☕

One file

Your entire app compiles into a single executable PHAR.

Zero web

No routing, no sessions, no views — just the console kernel.

All Laravel

The container, the collections, the ecosystem you already love.

Delightful by default.

The boring parts are already done, so you can spend the afternoon on the fun ones.

Beautiful terminal output

Termwind lets you style the console with the utility classes you already know. Tasks, tables, spinners and progress bars are one method call away.

render('<div class="px-2 bg-fuchsia-400">Shipped!</div>');

Shipped!

Instant scaffolding

A working application, a first command and a passing test suite — in the time it takes Composer to finish.

Pest, pre-installed

Write expressive tests for your commands from the very first commit — expectations, datasets and all.

Scheduling built in

Attach a cron expression to any command and let one crontab entry run your whole application.

Ship a single binary

app:build compiles everything into one PHAR. Upload it, curl it, brew it — your users just run it.

You already know
how to write this.

If you have written an Artisan command, you have written a Laravel Zero command. Same signature syntax, same output helpers, same container — with a much smaller surface area around it.

  • Dependency injection in handle()
  • Prompts, confirmations and choices
  • Exit codes as first-class citizens
  • Scheduling next to the command
tests/Feature/ReleaseTest.php
<?php

it('releases a patch version', function () {
    $this->artisan('release --patch')
        ->expectsOutputToContain('Compiling PHAR')
        ->assertExitCode(0);
});

it('asks before overwriting a tag', function () {
    $this->artisan('release --patch')
        ->expectsConfirmation('Tag exists. Replace it?', 'no')
        ->assertExitCode(1);
});

Go on. Build something small.

Free, open source, MIT licensed. Requires PHP 8.2 or higher.

Create your first command