What are the key differences between KeystoneJS and Strapi as tools to create CMS-driven apps?
Not to familiar with KeystoneJS but from the look of it they are very similar. Strapi looks like it has a more extensible API but overall its the same concept. I have used Strapi for several projects and it's fast to work with, you can have Strapi up on Heroku with a fully built schema in less than an hour.
One thing between the two is GraphQL support, Strapi is making a significant push to get involved in GraphQL world, I believe in-order to keep up with Tipe.io.
Setting up GQL + Strapi + Nuxt / Next is wonderful for creating a SSR application.
I've been enjoying working with KeystoneJS v5 for over a year on multiple projects. I had the same question as you and I picked Keystone over Strapi (even when git stars and community were higher) because I was looking for a simple file based Backend Generator.
This line express it: schema => ({AdminUI, GraphQLApi})
.
I needed to quickly define (and later easily modify) the Information Arquitecture of my backend, and seen it reflected automatically in a CMS and the API.
(Strapi users, correct me if I'm wrong)
I saw that Strapi had more focus on building a Drag and Drop (no code) way of building this backend. I couldn't find a straight forward way of using Strapi with files and get the CMS and API I was looking for. Seemed to me that was built for people that wanted a backend, but didn't wanted to write code.
I rather use my code editor functions (find/replace, multicursor) to define and modify my schema than a Drag and Drop components on the browser. Also use previous projects as my based code to build new ones.
My keystone projects get a really simple file structure where most comes out of the box and making custom mutations, AdminUI components, hooks, and data seeding was really simple.
Here is an example:
├── index.js // imports entities, hooks, initial-data, submodules
├── initial-data.js // imports seed/index.js and orchestastes how to create data
├── entities // for each entity (list): field types, access control, hooks, adminUI configs
│ ├── index.js
│ ├── Users.js
│ ├── Books.js
│ ├── Loans.js
│ ├── Authors.js
│ ├── ...
│ └── Categories.js
├── extendGraphqlSchema // pretty easy to add new custom Graphql types, mutations and queries
│ ├── index.js
│ ├── types
│ ├── queries
│ └── mutations
├── hooks
│ ├── index.js
│ ├── user_beforeUpdate.js
│ ├── book_validateInput.js
│ ├── ...
│ └── loan_afterDelete.js
├── keystone-media-server // submodule I use on many Keystone projects
│ ├── adapters
│ ├── fields
│ ├── lists
│ ├── resolvers
│ └── seed
└── seed // list of functions to create a complete data example to test
├── index.js
├── createUsers.js
├── createBooks.js
├── createLoans.js
├── createAuthors.js
└── createCategories.js
At the time of this writing (nearly a couple years after this question was posted), Keystone 5 is oriented around graphql, so that is no longer a prime differentiator between the two. Keystone 4 is still being maintained as a REST-first framework.
Strapi is GQL-first now and has a larger community.