Back to Blog
Directus: When Your 'Headless CMS' is Really Just Your Database
8 min readAug 18, 20260 views

Directus: When Your 'Headless CMS' is Really Just Your Database

Tired of syncing your database schema with your CMS? Directus flips the script, turning any SQL database into a powerful headless CMS and app builder. No more duplicating efforts, just a direct line to your data.

BackendDatabaseAPIFull-Stack
Share

by Sunil Band

Your Database is the Source of Truth. Why Isn't Your CMS?

We've all been there: you design a pristine database schema, build out your application logic, and then, inevitably, you need a way for non-developers to manage content. What's the go-to solution? A headless CMS. You spend days defining content models, replicating your database structure, and writing API wrappers. It feels like you're building the same thing twice, just with different tools.

This duplication isn't just annoying; it's a source of bugs. Schema drift between your database and CMS means manual updates, potential data inconsistencies, and a higher cognitive load for the team. What if your database was your CMS? What if you could get all the benefits of a powerful content management system, complete with a beautiful admin panel and instant APIs, directly from your existing SQL database?

That's where Directus comes in. It's not just another headless CMS; it's a data platform. Directus connects directly to your SQL database, introspects its schema, and provides a real-time API and an intuitive admin interface for managing that data. You're not defining content models in Directus; you're just defining your database schema, and Directus exposes it.

The Directus Philosophy: Data-First

The core idea behind Directus is simple yet profound: your database schema is your content model. When you connect Directus to a new or existing SQL database, it reads your tables, columns, and relationships. It then automatically generates a comprehensive API (REST and GraphQL) and a dynamic admin application (the Data Studio) that allows users to create, read, update, and delete data directly in your database.

This data-first approach means several things. First, there's no proprietary data storage. Your data lives where it always has. Second, any changes you make directly to your database schema are immediately reflected in Directus. Add a column? It appears in the API and Data Studio. Change a data type? Directus picks it up. This eliminates the dreaded schema sync dance.

It's a powerful shift for full-stack developers. Instead of thinking about your CMS as a separate service that your application integrates with, you can think of Directus as an extension of your database. It's the user interface and API layer for your database, designed for managing structured content and data.

Getting Started: A Project Example

Let's spin up Directus and see this in action. We'll set up a simple products table in a PostgreSQL database and watch Directus bring it to life.

First, you need a database. I'll use Docker to quickly get a PostgreSQL instance running:

bash
docker run --name directus-db -e POSTGRES_DB=directus -e POSTGRES_USER=directus -e POSTGRES_PASSWORD=directus -p 5432:5432 -d postgres

Now, let's get Directus itself. The easiest way is via npx or Docker. I prefer Docker for self-hosting in production, but npx is great for local development:

bash
mkdir my-directus-project
cd my-directus-project

npx directus init

The npx directus init command will walk you through setting up your project. When prompted for the database, choose PostgreSQL and enter the connection details for the Docker container we just started (host: localhost, port: 5432, user: directus, password: directus, database: directus).

After initialization, start Directus:

bash
npx directus start

Directus will now be running, typically on http://localhost:8055. Open that in your browser, and you'll be prompted to create an admin user. Do that, and you're in the Data Studio.

Creating Your First Collection (Table)

Inside the Data Studio, navigate to "Data Model". Since our directus database is initially empty (apart from Directus's own system tables), you won't see any content collections. Let's create a products table directly in our PostgreSQL database using psql or any database client:

sql
CREATE TABLE products (
    id SERIAL PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    description TEXT,
    price DECIMAL(10, 2) NOT NULL,
    stock INTEGER DEFAULT 0,
    image_url VARCHAR(255),
    published_on TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

INSERT INTO products (name, description, price, stock, image_url) VALUES
('Wireless Headphones', 'Premium over-ear headphones with active noise cancellation.', 199.99, 50, 'https://example.com/headphones.jpg'),
('Smartwatch Pro', 'Fitness tracking, heart rate monitor, and notifications.', 249.00, 120, 'https://example.com/smartwatch.jpg');

Now, refresh the Directus Data Studio. You'll see products automatically appear under "Data Model" as a new collection. Directus has introspected the table, inferred data types, and is ready for you to use it.

Managing Data and Access

Click on the products collection. You'll see the two products we inserted, displayed beautifully in a table. You can now:

  • Add new items: Click "Create New" to add more products via a form generated based on your table schema.
  • Edit existing items: Click on a product to open an edit form.
  • Customize fields: In the Data Model, click on products and then on individual fields. Here, you can change how Directus presents the data (e.g., use a rich text editor for description, an image upload interface for image_url) without altering your underlying database schema. This is where Directus adds its powerful CMS-like capabilities.
  • Set up permissions: Under "Settings > Roles & Permissions", you can define granular access control for different roles (e.g., Public, Admin, or custom roles like Editor). This allows you to control who can read, create, update, or delete data in your products collection, down to individual fields.

Accessing Data via API

Directus automatically exposes a REST and GraphQL API for all your collections. For our products collection, you can hit the REST endpoint:

bash
curl http://localhost:8055/items/products

This will return a JSON array of your products. You can also filter, sort, paginate, and relate data using standard API parameters. For example, to get only published products with stock greater than 0:

bash
curl "http://localhost:8055/items/products?filter[stock][_gt]=0&filter[published_on][_nnull]=true"

The GraphQL API offers even more flexibility for complex queries. Directus provides a built-in GraphQL playground (usually at http://localhost:8055/graphql) where you can explore your schema and test queries.

Beyond Simple Tables: Relationships and Customization

Directus truly shines when you have more complex data models. If you add another table, say categories, and create a foreign key relationship between products and categories in your database, Directus will automatically detect this relationship. In the Data Studio, you'll then be able to link products to categories using a dropdown or a multi-select interface.

sql
CREATE TABLE categories (
    id SERIAL PRIMARY KEY,
    name VARCHAR(255) NOT NULL UNIQUE
);

ALTER TABLE products
ADD COLUMN category_id INTEGER REFERENCES categories(id);

INSERT INTO categories (name) VALUES
('Electronics'),
('Wearables'),
('Accessories');

UPDATE products SET category_id = (SELECT id FROM categories WHERE name = 'Electronics') WHERE name = 'Wireless Headphones';
UPDATE products SET category_id = (SELECT id FROM categories WHERE name = 'Wearables') WHERE name = 'Smartwatch Pro';

After refreshing the Data Studio, you'll see the category_id field in products transform into a relational picker, allowing you to easily assign categories. The API will also let you fetch nested data, like products?fields=*,category.name.

Directus also supports custom interfaces. If the default input types aren't enough, you can write your own custom Vue.js components to render and interact with specific fields, giving you full control over the editing experience.

Trade-offs and Considerations

While Directus is incredibly powerful, it's not a silver bullet. Here are a few things to keep in mind:

  1. Database Coupling: The strength of Directus (direct database connection) is also its potential weakness. If you're not careful, Directus's admin interface can expose your entire database schema. Granular permissions are crucial. Also, if your database schema is highly optimized for complex application logic and not content management, Directus might not provide the ideal editing experience out of the box.
  2. Performance: For extremely high-traffic, read-heavy scenarios, an ORM-based headless CMS might offer more built-in caching layers specific to its data storage. Directus relies on standard database optimizations and caching at the API gateway level. For most applications, this is perfectly fine, but it's something to monitor.
  3. No Schema Migrations: Directus doesn't do database migrations. It expects you to manage your database schema (e.g., with tools like Flyway, Liquibase, or Prisma Migrate) and then it adapts. This is by design, reinforcing the idea that your database is the source of truth, not Directus. If you're looking for a tool that handles both content management and database migrations in one, this isn't it.
  4. Learning Curve: While the basics are simple, mastering Directus's full capabilities (custom interfaces, hooks, flows, granular permissions) requires some dedication. It's a comprehensive platform, and understanding its underlying philosophy helps a lot.

Wrapping up

Directus offers a compelling alternative to traditional headless CMS solutions, especially for projects where the database is already the central hub of information. By treating your SQL database as the primary source, it eliminates schema duplication, streamlines development, and provides a robust, extensible platform for managing your data.

If you're tired of fighting with content models that diverge from your actual database, give Directus a serious look. The next step? Head over to the Directus documentation and try connecting it to an existing project's database. You might be surprised how quickly you can get a functional admin panel and API up and running without writing a single line of backend code.

More from the blog
Available for projectsReady to make something fun 🎈

Ready to build the next system?Wanna build something awesome together?

Currently accepting high-impact opportunities in frontend engineering and scalable web applications.Got a cool idea rattling around? Let's grab a virtual coffee and turn it into something people love. ☕