Understanding the .info.yml File in Drupal Module Developmentfor Drupal 8 , 9 , 10 , and 11

Last updated :  

Every module needs an ID card — a place Drupal can look to answer "what is this, and can I even run it?" before touching a single line of your PHP. That's the entire job of the .info.yml file. It's the one file every module absolutely must have, and in the previous lesson you already wrote one without fully knowing what each line does. This lesson goes back through hello_world.info.yml key by key.

What you'll learn in this lesson

  • Why .info.yml is the one file Drupal cannot discover a module without
  • What each of the five common keys actually controls, and which ones are truly required
  • The most common mistakes that silently keep a module from appearing at all

Why this file exists

Drupal doesn't scan your PHP files looking for modules — it scans for *.info.yml files. Find one, and Drupal registers a module by that name; find none, and as far as Drupal is concerned, your folder full of code doesn't exist. That's why, without this file, your module never shows up at /admin/modules at all — not disabled, not broken, just invisible.

The file, key by key

name: 'Hello World'
type: module
description: 'This is a Hello world module'
package: Custom
core_version_requirement: ^10 || ^11

name — required

The human-readable label shown at /admin/modules. This is what a site builder sees and clicks — not your machine name. Keep it short and genuinely descriptive; "User Login Enhancements" tells a future maintainer far more than "My Custom Module."

type — required

Always module for a module (the other values, theme and profile, are for Drupal's other two extension types). A typo here — modules instead of module is the classic one — makes Drupal silently ignore the whole file.

description — required

The one-line summary shown next to the module's name in the admin UI. Keep it under 255 characters and make it specific — "Displays a custom Hello World page at /hello" tells a site builder far more six months from now than "Custom module" does.

package — optional

Groups related modules under one heading in /admin/modules — Drupal core's own modules cluster under headings like "Core" this way. Omit it and your module lands in a generic "Other" bucket, which gets messy fast on a site with more than a couple of custom modules.

core_version_requirement — required in modern Drupal

Composer-style version constraint syntax: ^10 || ^11 means "any 10.x release, or any 11.x release" — the caret allows minor version updates within a major version, and || chains multiple allowed major versions together. This key replaced the older, simpler core: 8.x style and is what Drupal checks before letting an administrator even attempt to install the module on an incompatible version.

The one mistake that costs people the most time: after adding or changing an .info.yml file, Drupal's module list can still show stale data until you clear the cache (drush cr). If a module you just created refuses to appear, that's almost always the first thing to try — not a typo in your YAML.

Quick check: you write a perfectly valid .info.yml, but forget to include core_version_requirement entirely. What happens? (Answer: on a modern Drupal 9.4+/10/11 site this key is effectively mandatory — without it, Drupal treats the module as incompatible and won't let you install it, even though every other key is correct.)

Key takeaways

  • name, type, description, and core_version_requirement are effectively required — leave any of them out and the module either won't appear or won't install.
  • package is purely organizational — it changes where the module is grouped in the admin UI, nothing about its functionality.
  • core_version_requirement uses Composer's caret (^) and OR (||) syntax, not a bare version number.
  • When a module doesn't behave as expected right after editing its .info.yml, clear the cache before assuming the YAML itself is wrong.

Coming up next

The .info.yml file only ever tells Drupal a module exists — it can't make anything appear on screen. Next, in Basic Controller & Routing, you'll connect a URL to a piece of PHP that actually generates a page, the way /hello did in the last lesson.