DEV Community

Alex Spinov
Alex Spinov

Posted on

Directus Has a Free API: Turn Any SQL Database Into a Headless CMS

What is Directus?

Directus is an open-source data platform that wraps any SQL database with a real-time REST and GraphQL API, plus a beautiful admin app. Unlike other CMSs that force their own database schema, Directus works with YOUR existing database — PostgreSQL, MySQL, SQLite, MS SQL, Oracle, MariaDB.

Why Directus?

  • Free and open-source — self-host with no limits
  • Database-first — works with ANY existing SQL database
  • Auto-generated API — REST + GraphQL from your tables
  • Beautiful admin — no-code UI for content editors
  • Real-time — WebSocket subscriptions on data changes
  • Flows — visual automation builder (like n8n inside your CMS)

Quick Start

# One command
npx create-directus-project my-project

# Or Docker
docker run -d -p 8055:8055 \
  -e ADMIN_EMAIL=admin@example.com \
  -e ADMIN_PASSWORD=admin123 \
  directus/directus

# Admin panel at http://localhost:8055
Enter fullscreen mode Exit fullscreen mode

API (Auto-Generated)

# REST API — works for ANY collection
GET    /items/articles              # List articles
GET    /items/articles/1            # Get single article
POST   /items/articles              # Create article
PATCH  /items/articles/1            # Update article
DELETE /items/articles/1            # Delete article

# With filtering, sorting, relations
GET /items/articles?filter[status][_eq]=published&sort=-date_created&fields=title,content,author.name&limit=10

# GraphQL
POST /graphql
Enter fullscreen mode Exit fullscreen mode

JavaScript SDK

import { createDirectus, rest, readItems, createItem } from '@directus/sdk';

const client = createDirectus('http://localhost:8055').with(rest());

// Read items
const articles = await client.request(
  readItems('articles', {
    filter: { status: { _eq: 'published' } },
    sort: ['-date_created'],
    fields: ['title', 'content', { author: ['name', 'avatar'] }],
    limit: 10
  })
);

// Create item
const newArticle = await client.request(
  createItem('articles', {
    title: 'Getting Started with Directus',
    content: 'Your content here...',
    status: 'draft'
  })
);
Enter fullscreen mode Exit fullscreen mode

Real-Time Subscriptions

import { createDirectus, realtime } from '@directus/sdk';

const client = createDirectus('ws://localhost:8055').with(realtime());

await client.connect();

client.onWebSocket('message', (message) => {
  if (message.type === 'subscription') {
    console.log('Data changed:', message.data);
  }
});

await client.subscribe('articles', {
  event: 'create',
  query: { fields: ['title', 'author'] }
});
Enter fullscreen mode Exit fullscreen mode

Flows (Built-in Automation)

Trigger: Item created in 'orders' collection
  → Run JavaScript: calculate total
  → Send email: order confirmation
  → Webhook: notify shipping service
  → Update item: set status to 'processing'
Enter fullscreen mode Exit fullscreen mode

Directus vs Alternatives

Feature Directus Strapi Payload Contentful
Database Any SQL PG, MySQL, SQLite PG, Mongo, SQLite Cloud only
Existing DB Yes No (creates own) No N/A
API REST + GraphQL REST + GraphQL REST + GraphQL REST + GraphQL
Real-time WebSocket Plugin None Webhooks
Automation Flows (built-in) Webhooks Hooks Webhooks
No-code admin Yes Yes Yes Yes
Self-host Free Free Free No

Real-World Impact

A university had a legacy MySQL database with 15 years of research data — 200+ tables, complex relationships. They needed a modern API and admin panel without migrating data. Directus connected to the existing database in 10 minutes: instant API for all 200 tables, admin panel for researchers, zero data migration. What would have been a 6-month project took 1 afternoon.


Need an API layer for your database? I help teams build modern data platforms. Contact spinov001@gmail.com or explore my data tools on Apify.

Top comments (0)