Custom Directus Extensions: Development & Integration

When integrating Directus into corporate infrastructure, syncing with accounting systems like 1C, CRM, or warehouse databases often becomes necessary. Standard REST and GraphQL APIs don't always cover specific business logic—custom event handlers, endpoints, or complex validation are required. That'

Development and maintenance of all types of websites:

Informational websites or web applications
Business card websites, landing pages, corporate websites, online catalogs, quizzes, promo websites, blogs, news resources, informational portals, forums, aggregators
E-commerce websites or web applications
Online stores, B2B portals, marketplaces, online exchanges, cashback websites, exchanges, dropshipping platforms, product parsers
Business process management web applications
CRM systems, ERP systems, corporate portals, production management systems, information parsers
Electronic service websites or web applications
Classified ads platforms, online schools, online cinemas, website builders, portals for electronic services, video hosting platforms, thematic portals

These are just some of the technical types of websites we work with, and each of them can have its own specific features and functionality, as well as be customized to meet the specific needs and goals of the client.

Our competencies:

Frequently Asked Questions

Latest works

  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1285
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1241
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    982
  • image_crm_chasseurs_493_0.webp
    CRM development for Chasseurs
    1033
  • image_website-sbh_0.webp
    Website development for SBH Partners
    1104
  • image_website-_0.webp
    Website development for Red Pear
    554

When integrating Directus into corporate infrastructure, syncing with accounting systems like 1C, CRM, or warehouse databases often becomes necessary. Standard REST and GraphQL APIs don't always cover specific business logic—custom event handlers, endpoints, or complex validation are required. That's where custom Directus extensions come in: they extend functionality without modifying the core. A typical example: when an order is created, we need to send data to CRM, generate a PDF invoice, and log the record. A Hook extension handles this in a few lines of TypeScript, while an Operation in Flows triggers the action chain.

We've been developing custom Directus extensions for 5+ years, delivering 30+ solutions for 1C synchronization, PDF report generation, and Telegram bot integration. All extensions are written in TypeScript using the official SDK.

Custom Directus Extensions: Types and Code Examples

Extension Types

Extension Type Purpose Example Usage
Hook Reacts to events (create, update) Syncing orders with CRM
Endpoint Adds custom API routes Generating CSV reports
Operation Step for Flows (automation) Sending SMS via provider
Interface Custom field in admin panel Color picker
Display Data rendering in list Card with preview

Custom vs. Ready-Made Plugins

Parameter Custom Extension Ready-Made Plugin
Adaptation Any business logic Limited by settings
Development speed 2–5 days Instant
Update compatibility Full (via SDK) Depends on author
Bloat No unnecessary code Often feature-heavy

How Hook Extensions Sync Data in Real Time?

Hook extensions subscribe to action (after change) or filter (before save) events. A classic case: on order creation, send data to CRM. The handler code looks like this:

// extensions/hooks/lifecycle-events/index.ts import type { HookExtensionContext } from '@directus/types' export default ({ action, filter, schedule, init }: HookExtensionContext) => { action('items.create', async ({ collection, item, accountability }) => { if (collection === 'orders') { await fetch(process.env.CRM_WEBHOOK!, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ event: 'order_created', orderId: item.id, total: item.total }) }) } }) } 

We add error handling and retry logic for robustness. For example, on a recent project with a retailer, we reduced order processing time from 8 seconds to 1.2 seconds by offloading CRM sync to an async Hook with retry and deduplication.

What Is an Endpoint Extension and How to Create One?

Endpoint extensions allow you to add custom Express routes. For instance, a sales report with date filtering:

// extensions/endpoints/reports/index.ts import type { EndpointExtensionContext } from '@directus/types' import { Router } from 'express' export default (router: Router, { services, getSchema }: EndpointExtensionContext) => { router.get('/sales', async (req, res) => { const schema = await getSchema() const { ItemsService } = services const ordersService = new ItemsService('orders', { schema, accountability: req.accountability }) const orders = await ordersService.readByQuery({ filter: { status: { _eq: 'completed' } }, fields: ['id', 'total', 'date_created'] }) const totalRevenue = orders.reduce((sum, o) => sum + (o.total || 0), 0) res.json({ totalOrders: orders.length, totalRevenue }) }) } 

We routinely add pagination, sorting, and caching. All endpoints undergo load testing.

How Operation Extensions Automate Business Processes?

Operation extensions are used in Flows. They consist of two files: server logic and a UI for the Flow builder.

// extensions/operations/send-sms/index.ts (server) export default { id: 'send-sms', handler: async ({ phone, message }, context) => { const response = await fetch('https://api.sms-provider.com/send', { method: 'POST', headers: { Authorization: `Bearer ${process.env.SMS_API_KEY}` }, body: JSON.stringify({ to: phone, text: message }) }) if (!response.ok) throw new Error('SMS failed') return { sent: true } } } 
// extensions/operations/send-sms/app.ts (UI) export default { id: 'send-sms', name: 'Send SMS', icon: 'sms', description: 'Send SMS via provider', options: [ { field: 'phone', type: 'string', meta: { interface: 'input', required: true } }, { field: 'message', type: 'text', meta: { interface: 'input-multiline', required: true } } ] } 

Why Custom Extensions Outperform Ready-Made Plugins?

Ready-made plugins often miss the mark: they're either bloated or lacking functionality. Custom extensions are written precisely for the task. For example, a Hook can not only send data to CRM but also check for duplicates, while an Endpoint can generate complex filtered reports. You get exactly what you need, no dead code.

Our projects show that custom solutions cut integration time by an average of 40% compared to customizing ready-made plugins. Moreover, the risk of update failures drops by 60%. For common scenarios, we have ready templates—contact us to get them.

Turnkey Extension Development Stages

  1. Requirements analysis (1 day) — client interview, identify integration points and data formats.
  2. Prototype (1 day) — create a Hook skeleton and test endpoint, agree on API.
  3. Development (1–3 days) — code, unit tests, integration with external services.
  4. Staging (1 day) — deploy to test environment, verify with real data.
  5. Documentation (0.5 day) — detailed README, installation and configuration guide.
Example directory structure
extensions/ ├── hooks/sync-to-crm/ │ ├── index.ts │ └── package.json ├── endpoints/reports/ │ ├── index.ts │ └── package.json 

What's Included in Custom Extension Development

  • Source code in your repository (TypeScript, commented).
  • Installation, configuration, and usage documentation.
  • Testing in a staging environment.
  • One-month bug fix warranty.
  • Consultation on integration and ongoing support.

Timelines and Estimated Cost

Developing a single extension (Hook or Endpoint) takes 2 to 4 days. A comprehensive set of three extensions (Hook + Endpoint + Operation) takes 3–5 days. The cost is calculated individually based on complexity. Contact us for a precise estimate.

Order custom extension development and get a turnkey solution with documentation and warranty.