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

Dbml To Laravel Laravel Package

egyjs/dbml-to-laravel

Turn DBML schema definitions into ready-to-use Laravel code. The package parses your database markup and generates migrations, Eloquent models, and relationships, helping you move from diagram to working app faster while keeping database design and code in sync. Great for teams that design schemas v...

View on GitHub
Deep Wiki
Context7

Getting Started

Install and orient yourself in five minutes

composer require egyjs/dbml-to-laravel --dev
php artisan vendor:publish --tag=dbml-to-laravel   # config + stubs, if provided
php artisan list | grep -i dbml                    # confirm the actual command signature

Because the package is small (74 stars, single maintainer), do not assume the README's command names match the installed version — the php artisan list step above is the fastest way to see the real signature, options, and defaults for the version you pinned.

Where to look first, in this order:

  1. config/dbml-to-laravel.php (after publishing) — output paths for models and migrations, namespace, whether timestamps/soft deletes are added, stub locations.
  2. vendor/egyjs/dbml-to-laravel/src/Commands/ — the artisan command class is the true documentation. Read the $signature and the handle method; it tells you exactly which options exist (--path, --force, --no-migrations, etc.).
  3. vendor/egyjs/dbml-to-laravel/src/ parsers/generators — worth 20 minutes, because when output is wrong you will need to know whether the DBML parser or the Eloquent stub generator is at fault.

First use case — greenfield schema capture. Put a DBML file at database/schema.dbml:

Table users {
  id integer [pk, increment]
  email varchar [unique, not null]
  created_at timestamp
}

Table posts {
  id integer [pk, increment]
  user_id integer [not null]
  title varchar [not null]
  body text
}

Ref: posts.user_id > users.id

Run the generator, then immediately git diff the result before touching anything else. Your first run is a calibration exercise: you are learning the package's conventions (table→model naming, pluralization, how it renders belongsTo/hasMany, whether it emits foreignId()->constrained() or the older unsignedInteger style) so you can decide what to override with stubs and what to accept.

Implementation Patterns

Treat the DBML file as the committed source of truth, not a one-off scaffold. The package is most valuable when database/schema.dbml lives in version control next to your migrations, and schema changes start as a DBML edit reviewed in a PR. That gives you a readable, diagram-able diff of intent before any PHP is generated.

Design in dbdiagram.io, generate in Laravel. The normal loop: sketch relations visually, export DBML, drop it in the repo, run the generator, review the diff, php artisan migrate:fresh. This is where the package earns its keep — relationship wiring (Ref: lines → belongsTo/hasMany) and migration column types are the tedious part of scaffolding, and they are exactly what it automates.

Generation order for a real project:

  1. Generate into a clean app first (php artisan migrate:fresh) to validate the schema actually runs.
  2. Then point the config at your real app/Models and database/migrations once you trust the output.
  3. Keep the generator in require-dev so production deploys never depend on it.

Handle many-to-many and pivots explicitly. DBML expresses M2M through a join table with two Ref: lines. Check what the generator produces there — you generally want a bare pivot model (or none at all) plus belongsToMany on both sides, and generators frequently emit a full Eloquent model with $fillable you don't want. Decide your convention once and encode it in the stub.

Brownfield pattern — generate to a scratch directory. Do not aim the generator at an existing app's app/Models. Point the output config at something like app/Models/Generated/ and database/migrations/generated/, then copy across only what you need after reading the diff. This keeps the package from silently overwriting hand-tuned models, casts, accessors, and relationships you added manually.

Stub customization is the main extension point. Publish the stubs and edit them once for your house style: declare(strict_types=1), #[Fillable] attributes vs $fillable arrays, enum casts, protected $casts for timestamp/json columns, base model class, and your Pint/PHPStan-friendly formatting. Ten minutes of stub editing saves you a post-generation cleanup pass on every regeneration.

CI guardrail. Add a job (or a pre-commit hook) that regenerates the schema into a temp directory and fails if the output differs from what's committed. This turns "someone forgot to regenerate" into a build failure and keeps DBML and migrations honest.

Gotchas and Tips

Regeneration is destructive — assume overwrite until proven otherwise. Run your first generations on a clean checkout, and always git diff before committing. Find out early whether the command needs --force to overwrite and whether it deletes orphaned files. If it does overwrite, your stub customization is your only protection, so get stubs right before you start hand-editing generated models.

Migration timestamps and FK ordering. Generated migrations need to run in dependency order (users before posts). The package usually handles this by stamping filenames in table order, but DBML declaration order is not necessarily dependency order — if you declare posts above users, verify the resulting timestamps. A migrate:fresh on a clean DB is the fastest smoke test, and it will surface ordering and constrained() failures immediately.

Foreign key rendering is where generators diverge from Laravel idiom. Watch for unsignedBigInteger + manual ->foreign() instead of foreignId()->constrained()->cascadeOnDelete(), missing onDelete propagation from your DBML [delete: cascade] settings, and nullable FKs becoming non-nullable (or vice versa). These are small edits but they are the ones you will make on every single regeneration if you don't fix them in the stub.

DBML features that commonly don't survive the round trip:

  • Composite primary keys and composite indexes.
  • Enum blocks — check whether they become PHP enums, string + Rule::in, or get dropped entirely.
  • Schema prefixes (public.users) and quoted identifiers with spaces or reserved words.
  • Column note: metadata (often ignored; you may want it as a model docblock).
  • [default: ...] expressions, especially function defaults like now().

Audit one table containing each of these before you commit to the package for a large schema.

Small-package risk management. At 74 stars and one maintainer, pin an exact version ("egyjs/dbml-to-laravel": "1.2.3") rather than using ^. If you rely on it heavily, fork it into your org and treat the fork as the dependency — the parser and stubs are small enough that maintaining a fork is realistic, and it removes the bus-factor concern entirely.

Version compatibility. Last release is dated 2026-06-03, so it's actively (if infrequently) updated. Check the composer.json constraints for laravel/framework and php before adopting; a package this size often lags on major Laravel bumps. If you're on the newest Laravel major, test on a throwaway branch first.

Debugging a bad generation. When output looks wrong, don't guess — dump the intermediate representation. Most DBML parsers expose a toArray()/getTables() step; write a five-line tinker script to print the parsed table structure and confirm whether the bug is in parsing (your DBML is being misread) or in generation (the parser is fine, the Eloquent output is wrong). That single step separates a DBML syntax problem from a package limitation, and it's the difference between a 5-minute fix and an afternoon of frustration.

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