A review of Strapi, the Node.js headless CMS
One name you can't ignore is Strapi.
In this post I'll run through some of the most important criteria we consider when using a headless CMS.
Strapi is the leading open source headless CMS. It’s written entirely in Javascript, it’s self-hosted and allows you to customise the admin panel as well as the API. Without diving too deep into more advanced features, you can get up and running with a flexible data structure in under 5 minutes.
Requirements / setting up
Strapi only requires Node.js, and leaves the choice of database up to you. You can initialise a strapi project by simply running:
yarn create strapi-app my-project —quickstart
Omitting the “—quickstart“ flag allows you to specify the database of your choice, be that SQLite, PostgreSQL, MySQL, MariaDB or MongoDB. Straight away, that’s a really powerful piece of functionality that’s really easy to implement. This is a pattern we see again and again using Strapi - power features out of the box; but only if you need them. This makes the devEx for Strapi as complex as you want to make it.
Starting the project is as simple as running yarn develop, which then runs the admin panel on localhost. Super easy and declarative! The setup process takes the “how” out of the equation so you only need to worry about “what” you need to get setup. This is miles away from the lengthy and often painful process of setting up your dev environment for Drupal which requires setting up a full LAMP/LEMP virtualisation.
Collaboration
Multiple developers modifying content types, editing api files and working on the customisation admin panel has the potential to be a nightmare to collaborate on. However, unlike Drupal which requires a “config export” in order to persist data changes on a content type, all content changes in Strapi are automatically controlled from the JSON in your codebase, which is safely version controlled with Git. It means that developers can work on their own and only worry about synchronising the codebase using git, reducing the risk of overwriting another dev’s changes.
Deployment
Being self-hosted gives you the flexibility to choose how to deploy your project. We chose AWS EC2 because the deployment process was familiar, but you could also choose from Heroku, DigitalOcean or Google Cloud if you wanted. The Strapi docs include guides for deploying to all of these platforms. The AWS guide provides instructions for deploying to EC2, connecting to an RDS instance for managing and hosting the database, and connecting to S3 for serving images.
The admin panel is automatically deployed to the same server that the backend gets deployed. It will be accessible via /dashboard. However you can also change it so that the admin panel is deployed elsewhere - set it up to point to another url in ./config/server.js, run yarn build to compile the frontend code, and you can then host that folder to serve the frontend from S3 & Cloudfront.
Time to learn
Creating and managing content types is simple and rapid, and if you are only planning on using Strapi as a simple CMS to serve content to a brochure or blog site, then that’s pretty much all you have to worry about.
If you need to extend the functionality beyond a basic site, then there’s a bit more reading to do - but it’s not at all overwhelming. Strapi’s well-maintained documentation makes it easy to learn the more advanced concepts like controllers, customisation and models - all of which will sound very similar to an MVC framework!
Pricing
The only significant difference in the paid-for tiers are the number of custom roles (the free tier still includes 3 roles which should suit most use cases) and the quality/ priority of support services. Other than that, every feature you’ll ever need is covered in the free tier. This is an enormous advantage over hosted solutions like Contentful which ramp up the price in order to increase your limits.
Typescript
A major disadvantage in our opinion, there’s no native support for Typescript ( yet ). Whilst it’s definitely on Strapi’s radar, and noting that there are workarounds out there like this one , it’s not the same as having native support. Nowadays we write our Javascript in Typescript at every opportunity, so this is almost a deal breaker for us.
For content creators
So how is the user experience for actually creating content? Strapi boasts that it’s developer-first - but does that mean the experience for content creators is secondary?
Strapi aims to prevent devs getting bogged down by the tech that they don’t need, and in practice this keeps the UI super simple, making it easy to understand for content creators. The admin panel provides enough powerful features like components, plenty of content types and “singles” to expose SEO fields or home page settings. Developers will control the fields and pages accessible to content creators, so that logging into the admin panel will show them everything they need, and nothing they don’t. In comparison, CMS’ like Drupal or Wordpress often pack in a load of features that content creators will never use, which makes for a more overwhelming UI and an intimidating user experience for non-tech-savvy content creators.
Updating core files
Because Strapi and the various plugins you’ll install are package dependencies, it’s really simple to upgrade your core Strapi version. Simply upgrade your version numbers in your package.json, then run yarn install to install the newly specified versions.
One potential hassle is when you’ve extended the admin files to add your own custom functionality to the admin panel. In this case, you might need to compare your version to the new changes on the repository. Not updating extensions could break your app.
Programming models and controllers
Often when using a CMS, you’ll need to make changes to adapt its behaviour to your requirements. Customising Strapi couldn’t be easier, and will be very familiar with any dev which has experience with a typical MVC framework. For example, if you create a content type “article” in the back office, then navigate to /api/articles, you’ll see that Strapi has automatically created a full folder structure with config, controllers, models and services.
By default, Strapi creates empty controllers and services for you- they make use of generic methods which you can override with your own custom functionality if you need to.
You could also do this the other way around: create the files in the folder structure you see here, and the new content type will be reflected on the admin panel. The great thing is that it’s all in code, which means there’s no ‘magic’ happening, it’s extremely customisable, and it’s super easy to collaborate on.
Controllers contain a set of methods reached by the client according to the requested routes you define. Essentially, they represent the C in the MVC pattern, and will contain most of your business logic:
When you setup content types (either collections or singles), the core methods are setup for you (find, findOne, count, create, update and delete) - but you can extend and customise all of these in the controller files:
And the lifecycle hooks concept allows you to access callbacks on a model, which opens up even more possibilities for customisation:
GraphQL Schema
Strapi delivers content through a RESTful or GraphQL API. The GraphQL interfaces are very intuitive and easy to use. Often, you’ll need to restrict certain endpoints or fields and in other CMS solutions where GraphQL has been added as an “afterthought”, this is needlessly complicated. Strapi, which has been built with GraphQL as a core feature, makes it easy to lockdown access to data by users or role.
Summary
So where does Strapi sit in the api economy?
Think of a scale - on one end is Wordpress, Drupal and Contentful - CMS providers that give you a lot of functionality out of the box, but make it harder for you to extend and edit because they have fairly rigid data structures that you should adhere to. Then on the other end are totally bespoke platforms - great when your business is totally unique but probably way too expensive for most use cases.
So where does Strapi sit on the scale?
I think it's somewhere in the middle. It gives you enough functionality out of the box whilst being lightweight enough that you don't get locked into a certain way of doing things - essential when your digital product is changing and evolving over time. For your use case, Strapi could be a simple content provider with a couple of bespoke features, but you have the tools to scale it to a fully custom API.
When should you use Strapi? If your project matches the pattern of many others — CRUD operations for most entities, core features covered by the Strapi plugins, and a bit of custom business logic— I think Strapi can save you an enormous amount of time writing that code as well as provide you with a content management solution out of the box. Strapi outshines all traditional CMS solutions in this respect, and it’s cheaper, more flexible and more dev-friendly than the modern CMS alternatives, too.
However, if you are implementing a significant feature set that doesn’t suit a traditional CRUD based model, or is so custom that bootstrapping the API wouldn’t save you much time, then you might be best implementing a completely custom node based backend, like we often do with our Serverless stack.
TLDR:
- Strapi is developer-first, but not at the cost of the content creator’s experience.
- It takes under 5 minutes to get started with a simple CMS that would be perfect for serving content to a brochure site or blog, but it will take up to 3-5 hours to get familiar with the more advanced concepts.
- The free tier covers most use cases.
- Front-end agnostic - truly headless, not just decoupled.
- Lack of typescript support 😭