Installing and configuring draftsmaninc/draftsman in a Laravel
application, and rendering saved graphs from the command line and CI.
The package hasn't been published on Packagist yet, so start by adding it to the
repositories block of your composer.json (add the block at
the end of the file if you don't have one):
"repositories" : {
"draftsman" : {
"type": "vcs",
"url": "https://github.com/draftsmaninc/draftsman.git"
}
}
Then install it via Composer. Draftsman is a development tool, so it belongs in require-dev:
composer require --dev draftsmaninc/draftsman:dev-main
Publish the config file with:
php artisan vendor:publish --tag="draftsman-config"
This is the contents of the published config file:
return [
'package' => [
// Path (relative to project root) where models live.
'models_path' => env('DRAFTSMAN_MODELS_PATH', app_path('Models')),
// Path (relative to project storage) where snapshots are saved.
'snapshot_path' => env('DRAFTSMAN_SNAPSHOT_PATH', storage_path('draftsman/snapshots/')),
// Path where graph documents are saved.
'graphs_path' => env('DRAFTSMAN_GRAPHS_PATH', base_path('draftsman')),
// Explicit node/npm binaries for Browsershot renders.
'node_binary' => env('DRAFTSMAN_NODE_BINARY'),
'npm_binary' => env('DRAFTSMAN_NPM_BINARY'),
],
];
Every key has a consumer — runtime capabilities (like which render formats work) are reported by the config API endpoint, not configured:
models_path — where Draftsman looks for your Eloquent models, relative to the project root.snapshot_path — where draftsman:snapshot writes its diagnostic dumps, relative to project storage.graphs_path — where saved graph documents land. This deliberately lives in the project root (draftsman/ by default) rather than storage/, so graphs are version-controlled with the code — mirroring Laravel Blueprint's draft-in-repo pattern.node_binary / npm_binary — explicit binaries for Browsershot renders. Web servers often run with a minimal PATH that misses version-managed node (nvm, Herd, volta) — set these when a render works from the CLI but 500s over HTTP. Null uses Browsershot's defaults.
Open /draftsman in your app (e.g. http://your-app.test/draftsman).
The bundled frontend reads your Eloquent models — including vendor models and pivot
tables your relations reach — and lays them out as an interactive diagram. Graphs you
save land as JSON documents in graphs_path, so they are version-controlled
with your code.
For a support/diagnostic dump of what Draftsman sees (models, config, about report), there is also:
php artisan draftsman:snapshot # writes to snapshot_path
php artisan draftsman:snapshot --path=... # or a specific file/directory
Any graph saved from the Draftsman UI (stored as
<graphs_path>/<slug>.json) can be rendered to a
self-contained file:
php artisan draftsman:render teams # draftsman/teams.html
php artisan draftsman:render teams --format=png # needs Browsershot, see below
php artisan draftsman:render teams --path=docs/erd.html
| Format | Needs | Notes |
|---|---|---|
html | nothing | Static, no JavaScript — safe to commit or serve anywhere |
png / jpeg / pdf | Browsershot | Headless-Chrome capture of the same page |
svg | — | Not available yet |
The html format works everywhere with zero extra dependencies. For image
and PDF output, opt in to Browsershot in the host app:
composer require spatie/browsershot
npm install puppeteer
npx puppeteer browsers install chrome-headless-shell # the browser it drives
Rendering the committed graph document on every push keeps a diagram in your repo (or build artifacts) that never drifts from the saved graph:
# .github/workflows/erd.yml
name: Render ERD
on:
push:
paths: ['draftsman/*.json']
jobs:
render:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: shivammathur/setup-php@v2
with: { php-version: '8.3' }
- run: composer install --no-interaction --prefer-dist
- run: php artisan draftsman:render teams --path=docs/erd.html
- uses: stefanzweifel/git-auto-commit-action@v5
with: { commit_message: 'Update rendered ERD' }
For png/pdf in CI, add Browsershot and Puppeteer before the render step:
- run: composer require spatie/browsershot
- run: npm install puppeteer
- run: npx puppeteer browsers install chrome-headless-shell
- run: php artisan draftsman:render teams --format=png --path=docs/erd.png