Drupal module development is how a Drupal site gets features that nobody else needed in quite the same way: an approval workflow that matches your organization, a product finder with your own rules, a nightly sync with your CRM. Drupal core and thousands of contributed modules cover most needs, and a custom module fills the gap between them and your requirements. It is one of the main parts of our Drupal development services.
You get a module that installs like any other, keeps its settings in Drupal configuration, respects Drupal's permission and caching systems, and comes with automated tests and a README. Because it follows Drupal's own architecture, it keeps working through core updates instead of becoming the reason you cannot update.
Custom Drupal Module Development Services We Offer
| Module type | Examples | What it means for you |
|---|---|---|
| Small custom modules | A custom block, form, field formatter, token or hook implementation | A targeted change without patching anything else |
| Business logic modules | Custom content entities, workflows, calculators, eligibility rules, admin settings forms and permissions | Your process modeled in Drupal, not worked around |
| Integration modules | CRM, ERP, payment gateway, single sign-on or third-party API connections with queued sync | Data moves between systems without manual exports |
| Plugins for existing systems | Views display styles and filters, field types and widgets, block plugins, migrate source plugins | New capability that editors use through familiar screens |
| AI features | Content suggestions, summaries, alt text and semantic search built on the Drupal AI module | AI help for editors, with a human approving the output |
| Contrib patches | Fixes or small features for contributed modules, submitted upstream where appropriate | Problems fixed at the source, not hidden in your codebase |
| Drupal 7 module ports | Rewriting Drupal 7 custom modules for Drupal 10 or 11 | Custom features survive the move off an unsupported version |
What Is Drupal Module Development? The Anatomy of a Module
A Drupal module is a folder of code that Drupal discovers, installs and runs as part of the site. Modern Drupal, from version 8 onward, is built on Symfony components, so a module is mostly object-oriented PHP organized into well-known files and classes. Knowing the parts helps you read a quote or review code:
| File or folder | Purpose |
|---|---|
| my_module.info.yml | Declares the module's name, description, dependencies and supported core versions |
| my_module.module | Procedural hook implementations, where still used |
| my_module.routing.yml | Maps URLs to controllers and forms, with access requirements |
| my_module.services.yml | Registers services and event subscribers for dependency injection |
| my_module.permissions.yml | Defines permissions that site admins grant to roles |
| my_module.libraries.yml | Declares CSS and JavaScript assets the module attaches |
| src/ | PHP classes: controllers, forms, plugins, entities, services and hook classes |
| config/install and config/schema | Default configuration and the schema describing it |
| templates/ and tests/ | Twig templates and PHPUnit tests |
Hooks, events and plugins
Modules change Drupal's behavior in three main ways. Hooks let a module react to things Drupal does, such as saving a node or altering a form; since Drupal 11.1 they can be written as methods on classes marked with a Hook attribute, instead of only as procedural functions. Events, from Symfony, let a module subscribe to request and system events. Plugins are swappable units such as blocks, field widgets and Views filters, discovered automatically from attributes or annotations. Choosing the right mechanism is a large part of writing a module that stays maintainable. A module that alters a form through a hook, for example, survives core updates far better than one that copies and replaces the whole form, and it leaves other modules free to make their own changes to the same form.
Drupal Module Development Process We Follow
- Check contrib first (1 to 3 days). We search drupal.org for contributed modules that already cover the need, fully or partly. Configuring or extending a maintained contributed module often beats writing new code.
- Specification (about 1 week). Data model, screens, permissions, configuration, integrations and edge cases written up for your approval, with a fixed quote.
- Build (1 to 6 weeks). Development in DDEV against a copy of your site, using Drush code generators for scaffolding and dependency injection throughout. You review progress on a staging site.
- Tests and code review (in parallel). Unit, kernel and functional PHPUnit tests for the core logic, PHP_CodeSniffer with Drupal coding standards, and PHPStan static analysis.
- Deployment (1 to 2 days). The module ships through Composer and Git, configuration through config import, and any data changes through update hooks so every environment ends up the same.
- Handover. README, configuration notes, permissions list and a walkthrough for site administrators.
Drupal Integrations: Connecting Drupal to CRM, ERP, SSO and Payment Systems
Integration modules are where custom Drupal work earns its keep, and where shortcuts hurt most. A form that posts directly to a CRM during the page request fails when the CRM is slow. We build integrations to survive that:
- Queued sync. Outgoing data goes into Drupal's Queue API and is processed by cron or a worker, with retries and a dead-letter log for records that keep failing.
- Secrets out of code. API keys are stored with the Key module or environment variables, not in configuration exported to Git.
- Logging and alerts. Every sync writes to a dedicated log channel, and admins receive alerts when failures pass a threshold.
- Single sign-on. SAML and OpenID Connect logins through maintained contributed modules, with custom code only for role mapping and provisioning rules.
- Payments and commerce. Custom payment gateway plugins for Drupal Commerce when your provider has no maintained module.
Drupal AI Module Development
Drupal's AI module gives sites a common way to connect to AI providers such as OpenAI, Anthropic and others, so features are not tied to one vendor. We build on it rather than calling a provider directly. Typical features include suggested summaries and meta descriptions in the editor, generated alt text that an editor reviews, content tagging against your taxonomy, and semantic search that finds related content by meaning. Each feature runs on your own API keys, logs what it sends, and keeps a person in the approval loop for anything published.
Drupal 7, 8, 9, 10 and 11 Module Development: What Changed
Drupal 7 module development used procedural PHP, .info files and hooks for almost everything. Drupal 8 rebuilt the system on Symfony with services, plugins, YAML configuration and object-oriented code. Drupal 9, 10 and 11 kept that architecture and mainly removed deprecated APIs, raised PHP requirements and added features such as attribute-based plugin discovery and object-oriented hooks.
In practice, a well-written Drupal 9 module needs small changes to run on Drupal 11, while a Drupal 7 module needs a rewrite. Drupal 7 reached end of life in January 2025, so we do not start new Drupal 7 module development. We do port Drupal 7 modules to current Drupal, usually alongside a full site migration, and ongoing upkeep of finished modules sits with our Drupal maintenance services.
Contributed Module, Patch or Custom Drupal Module?
| Option | When it fits | Trade-off |
|---|---|---|
| Contributed module as is | A maintained, security-covered module does what you need | You accept its design choices and release schedule |
| Contributed module plus a patch | A good module has one missing feature or bug | The patch must be re-checked on each update until it is merged upstream |
| Contributed module plus a small custom module | You need to alter behavior through hooks, events or plugins | Small custom code to maintain, but no forked contrib code |
| Fully custom module | The requirement is specific to your organization | You own all of it, so quality and tests matter |
How We Test Custom Drupal Modules
Drupal supports several kinds of automated tests, and a custom module should use the cheapest kind that proves each behavior. Unit tests check pure PHP logic such as price calculations or data mapping, and run in seconds. Kernel tests boot a minimal Drupal with only the modules needed, which suits entity, configuration and service tests. Functional tests run a full site in a browser simulation to check pages, forms and permissions, and functional JavaScript tests cover interactive behavior.
For integration modules we also mock the outside API, so tests can simulate slow responses, errors and unexpected data without touching your live CRM or ERP. Tests run on every change in a CI pipeline such as GitHub Actions or GitLab CI, so a future update that breaks the module is caught before it is deployed.
Contributing Drupal Module Work Back to the Community
Not every custom module should stay private. When a fix or feature would help other sites, contributing it to the relevant project on drupal.org means the maintainers carry it forward and your site stops depending on a private patch. We submit patches and merge requests to contributed projects when the change is general, and we keep business logic that is specific to you in your own custom module.
If you want a generic module published as a new contributed project, we can prepare it for drupal.org, including documentation and a clear maintenance plan. Contribution is your choice; nothing is published without your agreement.
Drupal Module Development Deliverables
- Module code in your Git repository, installed through Composer.
- Configuration schema, default configuration and an admin settings form where needed.
- Permissions defined and documented, with route access checks on every page and endpoint.
- PHPUnit tests covering the core logic, passing in your CI pipeline or ours.
- Clean PHP_CodeSniffer and PHPStan reports.
- A README covering installation, configuration, dependencies and how to extend it.
- Update hooks for any data or schema changes, so deployments are repeatable.
We also record the decisions behind the module: why a contributed option was rejected, which system owns which data, and what happens when an outside service fails. That record matters more than the code comments when someone needs to change the module two years from now.
Success means the module does what the specification says, passes its tests, survives a core minor update without changes, and can be understood by the next developer who opens it.
Drupal Module Development Pricing
We price modules as fixed projects after specification. A small module, such as one block, form or formatter, has a set price. Larger modules are quoted from a starting price, and cost depends on the data model, the number of screens and permissions, the outside systems involved, how sync handles failures, and the level of test coverage you want.
Small Module
$900 one-time
One-time, paid upfront
- One focused custom module or contrib module patch
- Examples: custom block, form, field formatter or hook
- Built to Drupal coding standards
- Configuration exportable with the rest of your site
- Tested on staging
- 30 days support, 1 to 2 weeks
Custom Module
From $2,500 project
One-time, 50% upfront
- Business logic module scoped to your workflow
- Custom entities, plugins and services
- Admin settings form and permissions
- Views integration for listings and reports
- Automated PHPUnit tests and documentation
- 60 days support
- 3 to 5 weeks
Integration Module
From $4,500 project
One-time, milestone billing
- Connects Drupal to a CRM, ERP, payment gateway, SSO or API
- Queued and scheduled sync with retries
- Logging and admin alerts
- Secure credential storage
- 60 days support
- Add-on
- Module updates for new Drupal versions: from $300
All prices in USD. Need something different? Ask for a custom quote.
For a module that is part of a larger build or migration, send us your requirements for a custom quote.
Mistakes in Custom Drupal Modules We Get Called to Fix
- Static service calls everywhere. Code that calls the global Drupal class instead of using dependency injection, which makes it hard to test and replace.
- Missing cache metadata. Render arrays without cache tags and contexts, so pages show stale content, or worse, one user's personalized content is cached and shown to another.
- Routes without access checks. Admin pages or JSON endpoints that anyone can reach by guessing the URL.
- Raw SQL built from strings. Queries assembled by hand instead of through the database API with placeholders, which opens the door to SQL injection.
- Configuration without schema. Settings that cannot be translated or validated, and that break configuration import.
- No update hooks. Data changes made by hand in production that no other environment knows about.
Who Needs Custom Drupal Module Development
A good fit if you:
- Run Drupal 10 or 11 and have a workflow or integration that contributed modules do not handle.
- Have custom Drupal 7 modules that must move to current Drupal.
- Inherited custom modules that block updates and need rewriting properly.
- Want AI features in the editor that run on your own provider keys.
Probably not a fit if you:
- Need something a maintained contributed module already does; we will point you to it.
- Want new Drupal 7 development; we only port Drupal 7 code forward.
- Are learning module development yourself; the drupal.org documentation and its step-by-step tutorials are the better starting place.
Related Drupal and Integration Services
Modules often go hand in hand with front-end work, handled by our Drupal theme development team, and with ongoing upkeep through our Drupal support plans. For connections between several platforms, see our CMS integration service.