Weave 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

Blacksmith Laravel Package

grafite/blacksmith

Grafite's Blacksmith is a Laravel scaffolding package that forges CRUD code from your database schema, generating models, controllers, routes, and views so you can quickly build admin panels and backend prototypes with less boilerplate.

View on GitHub
Deep Wiki
Context7

Getting Started

Day one: confirm what the package actually is. The metadata is contradictory — the package description advertises a schema-driven CRUD scaffolder ("point it at a table, get model/controller/routes/views"), while the operating assessments describe a thin Forge rebuild trigger. Resolve this before you write a line of integration code:

composer require grafite/blacksmith
php artisan vendor:publish --provider="Grafite\Blacksmith\BlacksmithServiceProvider"
php artisan list | grep -i black
cat vendor/grafite/blacksmith/composer.json   # check PHP/Laravel constraints and license
ls vendor/grafite/blacksmith/src             # read the service provider first

The service provider's register()/boot() tells you which of the two packages you actually installed: a commands([...]) array of rebuild commands, or generator commands plus view/config stubs. Everything downstream depends on this answer.

If it's the rebuild tool (the day-to-day use case):

  1. Read the published config/blacksmith.php. It is the source of truth for the Forge API token, server ID, site ID, and the rebuild step list. Grab the IDs from the Forge URL: forge.laravel.com/servers/{server}/sites/{site}.
  2. Move secrets into .env immediately so staging and production don't share a token:
BLACKSMITH_FORGE_TOKEN=...
BLACKSMITH_SERVER_ID=123456
BLACKSMITH_SITE_ID=789012
  1. Point the config at a non-production Forge site, SSH in as forge, and run the command exactly as the deploy script will:
sudo -u forge php artisan blacksmith:rebuild   # verify the real name via `artisan list`

If it's the CRUD scaffolder: run the generator against a single throwaway table first, diff the output, and check whether generated views/controllers match your conventions before generating anything you intend to keep.

First real use case: replace a hand-maintained Forge deploy script with one artisan invocation, so composer install, migrate, cache clears, and queue restarts are identical across staging and production instead of drifting apart.

Implementation Patterns

Forge deploy script integration. Keep git pull and environment-specific steps in Forge's deploy script; delegate the rebuild sequence to the package.

cd /home/forge/example.com
git pull origin main
composer install --no-dev --no-interaction
php artisan blacksmith:rebuild   # confirm name from `artisan list`

Per-environment config, never hardcoded. Use distinct Forge sites for staging and production and verify what Laravel actually loaded after each deploy:

php artisan config:show blacksmith    # Laravel 9+

Wrap it in your own command. Business logic belongs in your app, not in vendor/.

// app/Console/Commands/Deploy.php
public function handle(): int
{
    $this->call('down');                 // maintenance mode for schema changes
    Artisan::call('blacksmith:rebuild'); // or inject the package's service
    $this->call('up');
    $this->warmCaches();
    return self::SUCCESS;
}

This survives package upgrades, gives you a single entry point for pre/post hooks (Slack notify, DB snapshot, cache warm), and means a failed rebuild can restore the site instead of leaving it down.

Gate deploys on CI. Trigger the Forge webhook from GitHub Actions only after tests pass; store the webhook URL and token as repository secrets.

- name: Trigger Forge deploy
  if: success()
  run: curl -fsS -X POST "${{ secrets.FORGE_DEPLOY_WEBHOOK }}"

-f matters — a silent 200-on-failure is how you end up shipping a stale commit.

Testing. If the package uses Laravel's HTTP client, fake it in a feature test and assert both the exit code and the outgoing request:

Http::fake();
$this->artisan('blacksmith:rebuild')->assertExitCode(0);
Http::assertSent(fn ($req) => str_contains($req->url(), '/deploy'));

Assert exit codes explicitly; Forge's script will happily continue past a non-zero exit unless you check.

Cache re-warm as a follow-up job. If the rebuild clears caches, schedule a job that hits key routes rather than letting the first user absorb the cold start.

Gotchas and Tips

  • The package has an identity problem. Description says CRUD scaffolder; assessments say Forge rebuild wrapper. Until you've read vendor/grafite/blacksmith/src, treat every command name, config key, and README line as unverified. artisan list and the source are the only trustworthy documentation.
  • NOASSERTION license is a blocker, not a footnote. Clear it with legal before it touches production. If it can't be resolved, the fallback is a ~50-line internal command — cheaper to own than to inherit.
  • Assume unmaintained. Zero stars, zero dependents, no issue triage, no bus factor. Pin an exact version in composer.json, vendor or fork it, and plan to replace it. Do not adopt it as a platform dependency for a time-boxed convenience.
  • Config cache will bite you. After editing .env: php artisan config:clear locally, php artisan config:cache on the server. A stale cached Forge token produces 401s that look like Forge problems.
  • Deploy scripts run as forge. Variables exported in your SSH session are absent. Rely on the app's .env, never shell exports, and reproduce failures with sudo -u forge.
  • Deploy timeouts. Forge kills long-running deploy scripts. Heavy composer install or migrations can exceed the limit — split them into a queued job or a separate step rather than stuffing everything into one rebuild command.
  • Rebuilds are destructive. Migrations, cache clears, and queue restarts during traffic cause visible failures and drop in-flight jobs. Put the app in maintenance mode when schema changes are involved, and never run two rebuilds concurrently — there is no distributed lock.
  • Check idempotency before trusting it. Run the command twice on staging. If migrations or queue restarts duplicate or error, move them out of the package command and behind your own guard.
  • Scope the Forge token. A full-account token in a deploy script is unnecessary blast radius; issue the minimum scope and rotate it if it ever shows up in a log.
  • Debugging order: run manually as forge → read storage/logs/laravel.log → compare against the Forge deploy log. Most failures are token scope, a missing config key, or a working-directory mismatch — not package bugs.
  • If it turns out to be the CRUD generator instead: never generate over existing hand-edited controllers. Generate into a scratch branch, diff, and only then merge the pieces you want. The generated views are a starting point, not a design system.
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.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource