KeystoneJS Development for Custom Headless CMS

When domain logic doesn't fit into pre-built content types, KeystoneJS becomes the foundation. It's a code-first headless CMS where data schemas live in TypeScript, and the GraphQL API, admin panel, and Prisma schema are auto-generated. You don't waste time on CRUD wrappers: the system creates them,

Development and maintenance of all types of websites:

Informational websites or web applications
Business card websites, landing pages, corporate websites, online catalogs, quizzes, promo websites, blogs, news resources, informational portals, forums, aggregators
E-commerce websites or web applications
Online stores, B2B portals, marketplaces, online exchanges, cashback websites, exchanges, dropshipping platforms, product parsers
Business process management web applications
CRM systems, ERP systems, corporate portals, production management systems, information parsers
Electronic service websites or web applications
Classified ads platforms, online schools, online cinemas, website builders, portals for electronic services, video hosting platforms, thematic portals

These are just some of the technical types of websites we work with, and each of them can have its own specific features and functionality, as well as be customized to meet the specific needs and goals of the client.

Our competencies:

Frequently Asked Questions

Latest works

  • image_website-b2b-advance_0.webp
    B2B ADVANCE company website development
    1414
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1285
  • image_websites_belfingroup_462_0.webp
    Website development for BELFINGROUP
    982
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1241
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    982
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Website development for FIXPER company
    994

When domain logic doesn't fit into pre-built content types, KeystoneJS becomes the foundation. It's a code-first headless CMS where data schemas live in TypeScript, and the GraphQL API, admin panel, and Prisma schema are auto-generated. You don't waste time on CRUD wrappers: the system creates them, leaving you to focus on business logic. Within 7–10 days, you get a ready solution with custom fields, role-based access, and integration with any frontend—from Next.js to Angular. This approach reduces development cost and eliminates N+1 queries through a flexible API. Contact us to discuss your project.

Unlike admin-first CMS, KeystoneJS gives full control over data. You define relationships, hooks, computed fields—the system builds migrations via Prisma. We've used this approach in 10+ projects: from e-commerce stores with custom catalogs to corporate portals with multisite. According to our measurements, KeystoneJS accelerates backend creation by 1.5x compared to Strapi. Get a consultation from our engineer for a project estimate.

When to Choose KeystoneJS

KeystoneJS is suitable when:

  • Full control over data schema and business logic is required
  • The team is comfortable with Node.js and TypeScript
  • Custom access logic, complex computed fields, and data-level hooks are needed
  • GraphQL API is the primary interface for the frontend

It is not suitable if you need out-of-the-box hosting without DevOps or a rich UI for non-technical editors (then consider Strapi or Payload).

Why Choose KeystoneJS?

KeystoneJS outperforms traditional CMS due to its code-first approach. You are not limited by fixed structures: any relationships, computed fields, and hooks on create/update. GraphQL API provides the frontend with exactly the data it needs, without N+1 queries. According to the official documentation, KeystoneJS can reduce backend development time by 30–40% through auto-generation of CRUD operations.

Criterion KeystoneJS Strapi Payload CMS
Approach Code-first Admin-first Code-first
Typing TypeScript JS/TS partial TypeScript
GraphQL Full auto-generation REST + GraphQL REST + GraphQL
Customization Maximum Medium High
DevOps Required Built-in hosting Required

How We Set Up Access and Roles

In KeystoneJS, access rights are defined at the operation (create/read/update/delete) and field levels via access in each list. We implement a role model: admin, editor, author, anonymous. Built-in session support via cookie or JWT.

// Example: only author can edit their post access: { operation: { query: allowAll, create: ({ session }) => !!session, update: ({ session, item }) => session?.data?.id === item.authorId, delete: ({ session }) => session?.data?.role === 'admin', }, }, 

Process

  1. Discovery: define models, relationships, roles, integrations
  2. Design: create TypeScript schema, configure storage (local/S3)
  3. Implementation: write lists, hooks, access rules, customize Admin UI
  4. Testing: GraphQL queries, unit tests, load testing
  5. Deployment: Prisma migrations, Docker container, CI/CD

Configuration and Launch

// keystone.ts import { config } from '@keystone-6/core'; import { lists } from './schema'; import { withAuth, session } from './auth'; export default withAuth( config({ db: { provider: 'postgresql', url: process.env.DATABASE_URL!, enableLogging: true, idField: { kind: 'uuid' } }, lists, session, ui: { isAccessAllowed: (context) => !!context.session?.data }, server: { cors: { origin: [process.env.FRONTEND_URL!], credentials: true } }, }) ); 

Example Model: Post

// lists/Post.ts import { list } from '@keystone-6/core'; import { text, relationship, timestamp, select, image, document } from '@keystone-6/core/fields'; export const Post = list({ access: { operation: { query: () => true, create: ({ session }) => !!session, update: ({ session }) => !!session, delete: ({ session }) => session?.data?.role === 'admin', }, }, fields: { title: text({ validation: { isRequired: true } }), slug: text({ validation: { isRequired: true }, isIndexed: 'unique' }), status: select({ options: [ { label: 'Draft', value: 'draft' }, { label: 'Published', value: 'published' }, { label: 'Archived', value: 'archived' }, ], defaultValue: 'draft', }), content: document({ formatting: true, links: true }), author: relationship({ ref: 'Author.posts' }), featuredImage: image({ storage: 'local_images' }), }, }); 

GraphQL API and Frontend Integration

After running npx keystone dev, GraphQL Playground opens at http://localhost:3000/api/graphql. Example query:

query GetPosts { posts(where: { status: { equals: "published" } }, orderBy: { publishedAt: desc }) { id title slug author { name } } } 

In Next.js, use Apollo Client:

import { ApolloClient, InMemoryCache, createHttpLink } from '@apollo/client'; export const client = new ApolloClient({ link: createHttpLink({ uri: process.env.KEYSTONE_API_URL }), cache: new InMemoryCache(), }); 

What's Included

  • Data schema creation (lists, relationships, hooks)
  • Access and role configuration
  • Frontend integration (Next.js, Nuxt 3, Gatsby)
  • Storage configuration (local, S3)
  • Deployment and migrations
  • API and admin UI documentation
  • Editor team training
  • 1-month post-launch support

How KeystoneJS Accelerates Development

In practice, the code-first approach allows us to reduce initial setup time by 2–3x compared to admin-first CMS. We get a ready admin panel and API immediately after describing the schema. For example, in one e-commerce project, we saved 4 days just on the design phase, bringing significant cost savings to the client.

Typical Site Development Timeline

Phase Duration
Setup, DB config, base lists 1 day
3–5 models with relationships 2–3 days
Access and role configuration 1 day
Authentication + sessions 0.5 day
Frontend integration 2–3 days
Deployment + migrations 0.5–1 day
Total for medium site 7–10 days

For complex projects, 3–5 weeks. Get a consultation from our engineer for a project estimate.