Choose your path
You have a running site and have seen what the admin UI covers. Drupal work splits into four tracks with different skills and different documentation, and most developers live mainly in one. Pick yours here; if you come from another framework, the translation table below maps what you already know onto Drupal’s names for it.
The four paths
Section titled “The four paths”The honest first question is not “which code do I write?” but “do I need code at all?”. Everything in Your first hour (content types, fields, listings, blocks, permissions) was configuration, and configuration is versionable and deployable like code. If you want a finished site rather than a development track, the Drupal CMS user guide covers the packaged product end to end, entirely in the admin UI. Reach for a track below when configuration stops being enough, and prefer the earliest track that solves your problem: a view before a custom controller, a theme override before a markup-altering module.
The tracks share one foundation: the ten core concept pages. Decoupled developers need entities and access first; module developers most of them early; theme developers mainly the render pipeline and caching. When a track page assumes a concept, it links it, so you can start from the track and backfill.
Coming from another framework
Section titled “Coming from another framework”Drupal is built on Symfony components (the HTTP kernel, routing, the DI container, the console), so more of your knowledge transfers than the unfamiliar vocabulary suggests. The biggest mental shift is that Drupal’s data model and much of its behavior are defined in configuration rather than code; after that, the mapping is direct:
| You know it as | In Laravel / Symfony / Next.js | In Drupal | Start here |
|---|---|---|---|
| Routing | routes/web.php, #[Route] attributes, file-based routes | A *.routing.yml file per module mapping paths to controller classes, with access requirements declared on the route | Routes and controllers |
| Data layer / ORM | Eloquent models, Doctrine entities, Prisma schema | The Entity API: entity types in code, bundles and fields in configuration; query through entity storage, not SQL | Entities, bundles, and fields |
| DI container | Service container, autowiring, service providers | The same Symfony container: services in *.services.yml with autowiring, injected through constructors | Services and dependency injection |
| Middleware and events | Laravel middleware and listeners, Symfony kernel events | Symfony event subscribers for the request pipeline, plus hooks (attribute-based methods) for Drupal-specific extension points | Hooks and events |
| Templating | Blade, Twig, JSX components | Twig, selected by a template-suggestion naming convention instead of explicit render calls | Twig in Drupal |
| Background work | Laravel queues, Symfony Messenger | The Queue API with queue workers as plugins, processed on cron or by dedicated runners; Batch API for user-facing long operations | Background processing |
| CLI | artisan, bin/console | Drush for day-to-day site operations, plus core’s own command-line application (vendor/bin/dr from Drupal 11.4; php web/core/scripts/drupal on 11.3 and earlier) | Essential tools |
| Schema migrations | Laravel migrations, Doctrine migrations | Config import for structure, update hooks for one-time data changes; there is no per-table migration file | Configuration management |
| Caching | Cache facades, response caching | The Cache API: declarative cache tags, contexts, and max-age attached to everything renderable | Caching |
Two warnings for framework developers, both learned the expensive way:
- Do not reach for a controller first. In Laravel, a new page means a route and a controller. In Drupal, a listing page is a view, a landing page is content with a layout, and a settings page is a config form; custom controllers are for genuinely custom behavior. The earlier tracks are not the beginner versions, they are the shorter versions.
- Do not treat entities as rows. Entity queries, loading, and saving go through services that fire hooks, enforce access, and maintain caches. Bypassing them with raw SQL works until the first cache or access bug it causes.
Where to go next
Section titled “Where to go next”- Building a headless site: start with the Canvas Headless quickstart, and read Choose your front end to compare the architectures.
- Building features for a site today: start the module track with the first module tutorial.
- Making a site look right: start the theming track with the first theme tutorial.
- Shipping site builder work to production: the configuration management workflow makes admin-UI work deployable.
- Building with an AI coding agent: read Build with AI Agents before you start, so the agent works inside Drupal’s patterns instead of around them.
Was this page helpful?
Drupal is a registered trademark of Dries Buytaert.