Back to Articles

How we chose Directus as a Wordpress alternative

By Shash7. Posted on 30th Oct, 2022 - Updated on 17th Nov, 2023

How we chose Directus as a Wordpress alternative

If you're using Wordpress or something similar and want to make the jump to a headless CMS for your agency, I've written a review of Directus CMS.

In this review I'll go through the common gotchas of Directus and how we use it.

What is Directus

Directus is an open source headless CMS. Right now its at version 9 where its using nodejs underneath the hood.

Unlike other headless CMSes like Contentful, DatoCMS, etc, Directus is open source and rather easy to self host. Which makes is quite different in usage to these other options.

For Swipekit and this one agency website we're trialling Directus on, we found it quite nice to work with.

Directus in an agency environment

Let's be clear - most people who are using Directus and other headless CMS are working in agencies.

They are mostly used to Wordpress and work with multiple clients.

How does Directus fit into this workflow?

To work this out, we testing Directus with these tasks:

  • Does Directus has something akin to a CPT(Custom post type)?

  • Does Directus have custom fields(ACF or raw post_meta)

  • Does Directus have something similar to a repeater field and a flexible content type field?

  • How do relationships work between different content types?

  • How easy it is to use the CMS from an editorial perspective?

  • How does media management work?

  • Is there ACL?

  • How easy is Directus's api?

  • How does data migration work?

  • How do backups work?

  • Does Directus adhere to the 12 factor methodology

  • How easy it is to run Directus in a self-hosted environment.

  • How extendible is Directus?

  • What frontend can I use Directus with?

  • Is it fast?

  • Can this replace Wordpress?

Does Directus have something akin to a CPT?

Yes it does. They have content types that you can create and customize. Its very easy to create one and add fields inside it.

Here's the main bit - your content types are represented exactly as you define them in the database.

If you're coming from traditional CMSes like Wordpress and Craft CMS, you may know that they have a huge generic table(wp_posts for example) where everything is dumped in.

This makes it very flexible to create custom post types but eventually over time your site slows down as your website need to stitch together multiple wp_posts, wp_posts_meta and other random tables.

With Directus, your data model is represented exactly as your content type.

For instance, if you create a content type called articles and check your database, you'll see that Directus will have created an articles table with the fields exactly as you defined. This gives me great confidence that it will scale as my sites grow larger.

Does Directus have custom fields(ACF or raw post_meta)

Directus has the capability to add custom fields so yes it is possible to create fields similar to how you would do so in a Wordpress website + ACF plugin.

One thing to note is that Directus comes with heaps of fields by default and there are many ways to customize the fields including the way the data is stored all the way to how they look inside the CMS(colors, icons, etc can be edited for the fields)

You can also add custom fields by using community plugins created by other folks, or even create one yourself. I'll expand this futher below.

Does Directus have something similar to a repeater field and a flexible content type field?

Yep, they have a repeater field. It basically works like ACF except its way more low level.

Which means that you need to define the input type and the interface for each field. This isn't a big issue but it goes to show that Directus's approach is much more lower level.

Also, Directus stores the field value as a json.

Directus also support something similar to a flexible content type field. For the flexible content type field, things are much more tricky. Directus has something called a Many-to-All relation(M2A)

This relation is modelled in your database as a pivot table(called junction field in Directus docs) and this can link to various different tables instead of only one(thats where M2A is different from a many-to-many relationship)

This means that you'll need to create individual tables for intro section, content section, faq section, etc.

This isn't actually a bad approach, but the docs around this M2A field are almost non-existent.

And its obvious to say but this table can have multiple various fields inside them(like a repeater field for instance)

How do relationships work between different content types?

Quite smoothly. Directus supports all major relations like One-to-many, many-to-one, many-to-many and many-to-all, and it will create all the appriopriate relations and pivot tables.

From the UI perspective, its all seamless. You have the option to limit entries, create entry on the parent content type, etc.

How easy it is to use Directus from an editorial perspective?

This is a point of contention. Directus is a developer first CMS. Which is a great thing but the interface may be a bit bland for non-developers.

Overall, its definitely better than other headless CMSes like Contentful, Prismic and even Payload where tons of whitespace is wasted.

Directus was built by an agency and it definitely shows up. Whitespace is utilized, fields and list views are very compact, there are minor touches like if the user leaves a page without saving a dialog shows up asking them to save their changes.

They have an extremely clean aesthetic and I personally love it. Wordpress can get cluttered quickly based on the plugins you install - and almost every plugin these days have their own css styleguide(looking at you, ACF) which really make the whole experience jarring.

But on this note I prefer DatoCMS's UI to Directus, but only slightly. Directus is very much a developer first CMS and the styling on certain fields and the overall UI look more like a CMS then a editorial platform.

But again, these are minor issues and I still prefer Directus's UI than Wordpress and other old school CMS.

Directus also gives to ways to customize and whitelabel the CMS. For instance, if you're building a website for a client and want the delivery to look professional, you certainly want to whitelabel it slighly.

Here, you have the option to change the logo, add a background image to the login page, add some text here and other minor places to make your site whitelabelled. You can also add custom css to further customize the CMS.

For us, this is quite satisfactory, and Directus definitely has better options than other headless CMSes like Contentful and DatoCMS.

How does media management work?

Media management is very similar to how Wordpress does it. For instance, you have a dedicated media content type where media is stored. You can also do minor editing in this place.

Where does it store media?

By default, Directus stores media locally. But there are ways to setup a S3 connector.

Theoritically, you can connect to Digital Ocean spaces and Cloudflare R2 since they are compatible with the S3 api. But I haven't done this yet so I can't comment on this.

And if this doesn't work for your usecase, you can create your custom storage adapter too.

Is there ACL?

Yep. Directus comes with an extensive ACL(Access Control List) setup. You can customize it to tailor a specific user type to only view specific content types, toggle editing, deleting, etc.

I haven't dived deep into this but from what I can see, Directus has extensive ACL. For us, we only want 2 roles, admin and editor, and it fully meets our needs in this area.

How easy is Directus's api?

Directus offers two ways to consume the api. Via the rest api or via graphql.

They are both good but I've found directus sdk-js(the axios wrapper around their rest api) to be lacking in docs.

It seems that Directus is focusing more on graphql and if you're going to be integrating the api on your frontend, I'd recommend the graphql version.

What can you do with the api?

Apart from fetching data, you can do a surprising lot of stuff with the api. You can create folders, create content types, create fields, do crud stuff with data, etc.

I'm only using it for data fetching but with the amount of stuff you can do with the api programmatically, I can see people using it as backends for multi tenant saas or something similar.

How does auth work?

Directus's api has 2 ways to auth. One is a simple key you can define in your env and you can use it to get up and running with the api. This is great for server-to-server comms.

If you want more security, they have the oauth setup for this. I haven't tried this but then, I hate oauth(who doesn't!)

How does data migration work?

Directus stores the entire state of your site in the database. It makes Directus specific tables for this.

So if you want to move your database to another db, just clone the db and import it to your new db and it will work.

However there's a catch. If you're familiar with ACF, it creates acf-json locally in your project and this is supposed to be committed to your repo. With Directus, migrations will automatically be applied when you create/update fields and content types and therefore your database serves as the single source of truth for your schema.

This is bad because if you're working locally with a local Directus instance, and want to move to staging or prod, you'll need to also update your database tables manually.

This is something that's concerning me and there is some discussion going on about doing this correctly. I'll make a tutorial in the future about this topic when I resolve this.

But apart from that, migration is a breeze. There are no intermediately yaml files generated, nothing that breaks the 12 factor methodology apart from schema migration.

Update: Directus now has migrations support inside their cli.

How does this work?

Run npx directus schema snapshot ./snapshot.yaml inside your project folder.

This will generate a .yaml file. You need to perform this step locally.

Then run npx directus schema apply ./path/to/snapshot.yaml on your staging version.

This will apply all the new fields, tables, etc you've created, to your staging database.

I recommend chucking these scripts inside your package.json's script block, so you can run them as part of your ci/cd process.

For more information, checkout their cli docs.

PS: I'm not sure if this is compatible with Directus 9. I've tested this on the 10 version and it works well.

How do backups work?

Directus doesn't have an inbuilt backup tool. I wish there was.

Backups totally depend on your database server. For instance, if your using a managed mysql database via Digital Ocean or AWS RDS, they automatically take database backups.

And if you have a self hosted db setup, you'll need to write a cron job yourself that can automatic daily backups.

On this note, Directus supports mysql, postgresql and sqllite.

Does Directus adhere to the 12 factor app

12 factor app was created by the folks at Heroku that figured out how to have a painless devops update cycle. Basically, when you make your changes locally, how easy it is to push your updates to staging or production depend on how well aligned your website is to the 12 factor methodology.

I won't go in depth in this topic but here's a common scenario with wordpress. When you make your changes locally, you'll need to push the git repo to staging. Now do you commit the theme folder or the entire repo? And if you commit the entire repo, you'll need to leave out the uploads folder and/or specific plugins.

Point being that Wordpress breaks the 12 factor app fundamentally. There's no clear way to update changes. Some Wordpress frameworks like Roots have come close to solving this but there's no clear consensus on the Wordpress community on solving this.

Directus aligns well with the 12 factor app methodology. Your entire repo is commited to github. You setup a devops tool like Cleavr, Render, Heroku or something else so when you make an update, the server automatically gets updated.

Uploads are a non-issue since they are supposed to be gitignored. Each instance(staging, prod, etc) has their own way of connected to the storage depending on the env configuration.

And the env is pretty extensive. Almost everything can be configured from the env file.

How easy it is to run Directus in self-hosted environment?

Very easy, surprising.

Unlike other self-hosted apps where there are a ton of dependencies(install this, upgrade that, etc), Directus doesn't require anything. Just run npm install and you're good to go.

Oh you don't have a database connected? Just use sqllite for now.

Is it a memory hog? Nope - it uses less than 100mbs. Found this from my pm2 logs.

Directus is insanely well built and this shows in the setup phase. Just an absolute breeze to work with.

Its also very much configuration driven. They have a big fat list of env vars. Just copy that and chuck it in your devops tool(render, cleavr, etc) and it will work. Or create a .env file and drop everything in there.

What frontend can I use Directus with?

You can use any framework with Directus. I've used it with Nuxt and it works perfectly well.

Know that their sdk-js isn't a limiting factor. If you want to connect directus to a PHP site, you very well can do. Just use their rest api for connection.

They also have heaps of guides on connecting to various frontend frameworks. This is one area that's a total non concern.

How extendible is Directus?

This is a broad questions but from my needs, there are 2 bits that need to work.

Can you add custom fields interfaces?

Yes you can. This is similar to how you can create custom plugins for ACF. I haven't looked into this feature fully but underneath the hood, Directus is using Vue3 along with Typescript. Their extensions api also seems sensible.

Can you modify the admin UI

Yes and no. From what I could find, Directus can things called displays and you can only modify them.

A commons scenario is to modify the table UI so you can add buttons, computed columns, etc. Directus supports this but you'll need to write custom code for it.

Is it fast?

Firstly, headless CMSes by their very definition are blazingly fast, since all they have to do is serve api requests. But there are other areas that need to be discussed.

One common problem with old school CMSes like Wordpress is that scaling them is hard because of their weird database structure. This is where Directus and other modern CMSes significantly outperform them. Add 1000 posts to a Wordpress website and see your site slow down. Add 1000 posts to your articles content type in Directus and it will run happily since Directus creates a specific table for the content type.

But another area is the admin UI performance. Editors want a snappy UI and this is where Directus excels. The admin area uses vue along with vue router so the browser tab doesn't refresh again and again when you move between different pages.

Can this replace Wordpress?

Yes and no. There are two areas of contention.

Tech

As much as I dissed Wordpress in this post, you don't need to write a ton of code to get started.

Need a form? Install the Gravity forms plugin. Need to do SEO? Install Yoast.

With Directus, and generally speaking headless CMSes, you need to build out a lot of these integrations. That adds up your brief cost and that leads to the next area.

Sure you get a much cleaner codebase but you'll need to factor this in when you build out your client website.

Pricing

I still believe that Wordpress is ideal for sub 10k projects where all the client needs is a simple 5 pager website. These websites usually drive the revenue with marketing and there isn't much room to innovate tech wise anyways.

Directus is really meant for websites where you're going to have 3+ content types, maybe a products module, training module, etc. And you definitely need it if your client plans to scale massively, or you will be taking over an extremely large website.

All that being said, Directus is definitely meant for high 5 figure clients+.

Gotchas

Besides all the praise I'm giving Directus, there are some key areas of contention.

  • Please add a block editor to Directus core. There's a plugin that does this but from my experience with DatoCMS, a fully featured block editor radically changes the editorial process. You can programmatically create table of contents, add nofollow to outgoing links, etc. And you can also chuck in ads, sponsors, etc with a block editor.

  • Schema migration is a bit weird. There's no way to commit the schema to the github repo and this is a bit of a roadblock for me.

  • The plugin community is still very nascent and there needs to be more push to create a rock solid community around Directus. This is an area that the Directus team can reap benefits by creating a platform to build and market commercial plugins. Right now, the 3rd party plugins don't give me confidence. I've seen some plugins start off ambitious but they stop being supported and are left to rot.

  • The Directus team really needs to work on extensive documentation. Especially around their sdk-js and guides on setting up various data models like page-builder for example.

Conclusion

Choosing a CMS for your agency is no easy feat and I hope that you found this useful. Directus is a great CMS but don't let that deter you from choosing DatoCMS, Contentful or other headless CMSes.

This article reads like a Directus PR pitch.

Note that this isn't a puff piece on Directus.

For starters, Directus's docs are missing on a ton of undocumented features. They need to work on guides to show how to handle common scenarios such as setting up a simple blog, setting up an ecommerce data model, using stripe, handing 3rd party apis elegantly, etc. And DatoCMS is easier to use from the UI side of things.

But the reason that this article reads like a PR pitch is because I'm comparing it with Wordpress, which most developers loath - and finding something better than Wordpress is a rather low handling fruit.

Why not choose <insertyourheadlesscms>?

Directus made the cut because unlike Contentful, Prismic, DatoCMS, it is open source and you can self host it.

Granted they save a ton of dev time and you don't need to worry about data storage, security, db, etc, but they are insanely expensive.

DatoCMS - which I was using for this blog - charges a whopping $200 euros per month. And that's without the additional nickle and diming they do when you exceed your tier's limitations.

But why not choose <insertyouropensourcecms>?

Strapi and Keystone are two options in this space.

Unfortunately they both kinda suck.

Strapi is overhyped. I tried it a few years ago and it was insanely buggy. Keystone was great uptil v3 when the devs stopped supporting it - and published an entirely rewritten version without any backward compatibility - which goes on to show how quickly your favourite cms can be abandoned.


Lastly, I wrote this as a part of our agencies pitch to a client but it snowballed into a massive post. If you have any questions, please message me on twitter.

Also, If you like this article, I regularly post tech stuff on Swipekit's blog or on Snapfont's blog.

Update 8/11/2023

I've published an extension to this article detailing my experience using Directus for over an year.

Notes

  • The block editor I mention is quite different from Wordpress's block editor. Wordpress stores data in a nonsensical way whereas a block editor done well will store store data in json and output it in json. An ideal block editor also works somewhat like Notion's editor.

  • Directus supports translations but I haven't tested that out.

  • I actually really like DatoCMS but Directus made the cut specifically because of the self hosted option and its free tier.