DevOps & Platform Eng

Directus Backend Setup Simplified with Projen

Setting up a production-ready Directus backend feels like wrestling an octopus. Now, Projen aims to tame the beast, turning complex plumbing into a single config file.

Diagram illustrating the project-as-code setup for Directus using Projen

Key Takeaways

  • Projen and its `@wbce/projen-d9` template offer a "project-as-code" approach to automate Directus v9 backend setup.
  • This automation handles Dockerfiles, docker-compose, extension management, and build pipelines, saving developer time.
  • The system treats extensions as distinct packages within a pnpm workspace, allowing for code sharing.
  • While promising efficiency, the approach introduces a dependency on Projen and its templates for core project structure.

Has anyone actually enjoyed setting up a Directus v9 backend for production? If your hand isn’t raised, you’re not alone. It’s a task that often involves more Dockerfile wrangling and pipeline stitching than actual coding. Frankly, it’s enough to make a developer consider artisanal sourdough starters as a more engaging hobby.

Here’s the thing: Directus, bless its open-source heart, is a fantastic CMS. It can indeed be a surprisingly capable backend. But turning it into a strong production system requires a certain… discipline. And a lot of boilerplate. Enter Projen.

Projen is essentially a project scaffolding and automation framework. Think of it as a super-powered npm init on steroids, designed to automate the tedious bits. And a new template, @wbce/projen-d9, aims to automate the Directus plumbing. This is what they’re calling “project-as-code”: your project configuration lives in code, and you regenerate the output files whenever that config changes. Clever? Maybe. Necessary? That’s the million-dollar question.

What’s Under the Hood (of the Boilerplate)?

The d9 fork is essentially Directus v9, licensed under GPL-3. It’s the same CMS you know, capable of acting as your API, admin UI, and permission layer. Business logic gets tacked on as extensions—hooks, endpoints, custom UI panels, you name it. The promise here is that Projen handles all the setup for these extensions and the core Directus environment.

You kick it off with a command, naturally.

npx projen new --from @wbce/projen-d9

This spits out a .projenrc.js file. This file is your new god. It’s where you define everything your project needs, from extensions to release branches. It’s the user-facing surface of this whole operation.

import { D9Project } from '@wbce/projen-d9';
import { D9ExtensionType } from '@wbce/projen-d9-extension';

const project = new D9Project({
  name: 'my-backend',
  defaultReleaseBranch: 'main',
});

project.addExtension('audit-log', [D9ExtensionType.HOOK]);
project.synth();

Then, npx projen takes over. It synthesizes the rest: the Dockerfiles, the docker-compose.yml, the extension folders, the build pipelines, even GitHub workflows. It’s all driven by this single configuration.

The Automation Promise

When you run npx projen, it generates a docker-compose.yml that includes Directus, Postgres with PostGIS for geospatial capabilities (because why not?), and Redis for caching. It’s designed to mirror a production setup, which is… convenient. A Dockerfile is also generated, prepped for deployment, handling Node 22, pnpm, and extension builds. The whole shebang is designed to get you to a functional local dev environment with a single CLI command. No more hunting for the right Node version or figuring out Docker networking.

This is where the “project-as-code” mantra really sinks in. Your project’s structure and build processes aren’t scattered across a dozen files you might forget about. They’re defined in a single, version-controllable configuration. Re-syncing your project state is as simple as running npx projen again. It’s supposed to keep generated files in lockstep with your config. Sounds… clean. Almost disturbingly so.

When Extensions Are Just Packages

A neat trick here is how extensions are handled. Each extension becomes its own package within a pnpm workspace. This means you can actually share code between extensions. Need a common utility function for multiple hooks? Just add it as a separate shared package and let your extensions depend on it using workspace protocols.

Because every extension is its own package in a real pnpm workspace, we can share packages between extensions.

This modularity, while sensible, adds another layer to the configuration. You’re not just defining extensions; you’re defining their dependencies on shared libraries, all within the Projen ecosystem. It’s a level of abstraction that, for some, will be a godsend. For others, it’s just more things to learn.

The Deployment Picture

The generated Dockerfile is straightforward. It builds your Node environment, installs dependencies, copies your code, and runs npx projen build-extensions to get everything compiled. Then, it starts Directus. This process is designed to be pushed to a registry and run against your target database and cache. Simple, efficient, and presumably, less error-prone than manual Dockerfile creation.

But here’s my lingering skepticism: this entire edifice relies on Projen. If Projen itself has a bug, or if the @wbce/projen-d9 template is outdated or poorly maintained, you’re stuck. You’re also tying your project’s foundational structure to an abstraction layer. Is the complexity saved worth the dependency introduced? For a team already invested in Projen, absolutely. For someone just wanting to get a Directus project off the ground, it might feel like bringing a bazooka to a knife fight.

This approach feels like a logical — albeit slightly over-engineered — solution to a real problem. Directus is powerful, but its production setup isn’t exactly plug-and-play. Project-as-code, when done well, can indeed save significant development time. The question remains: is this done well enough to be universally adopted? Or will it become another niche tool for the already initiated?


🧬 Related Insights

Frequently Asked Questions

What does @wbce/projen-d9 do?

It’s a Projen template that automates the setup and configuration of a Directus v9 backend, including Dockerization, build pipelines, and extension management, following a “project-as-code” philosophy.

Is this better than manually setting up Directus?

For teams who value automation and want to enforce consistent project structures, yes. It significantly reduces manual setup time. For simpler projects, it might be overkill.

Can I use this with newer Directus versions?

The template is specifically for Directus v9, but the article suggests it can be adapted for other versions by modifying the template.

Written by
DevTools Feed Editorial Team

Curated insights and analysis from the editorial team.

Frequently asked questions

What does `@wbce/projen-d9` do?
It's a Projen template that automates the setup and configuration of a Directus v9 backend, including Dockerization, build pipelines, and extension management, following a "project-as-code" philosophy.
Is this better than manually setting up Directus?
For teams who value automation and want to enforce consistent project structures, yes. It significantly reduces manual setup time. For simpler projects, it might be overkill.
Can I use this with newer Directus versions?
The template is specifically for Directus v9, but the article suggests it can be adapted for other versions by modifying the template.

Worth sharing?

Get the best Developer Tools stories of the week in your inbox — no noise, no spam.

Originally reported by dev.to

Stay in the loop

The week's most important stories from DevTools Feed, delivered once a week.