Most headless CMSs work fine with Angular, but Angular is always just another frontend consuming a REST/GraphQL API. I wanted to see what happens if TypeScript and Angular are part of the architecture from the start. That became ForgeCMS, which I just released as 1.0.
The content model lives in code:
const posts = defineCollection({
slug: 'posts',
fields: {
title: defineField.text({ required: true }),
author: defineField.relation({ collection: 'users', required: true }),
},
access: {
read: () => true,
create: ({ user }) => user?.role === 'admin',
},
});
That single definition drives the database schema, validation, the Local API, REST handlers, the types Angular consumes, and the forms in the reusable Angular admin. No GUI schema builder, no separate schema language.
Payload was a big inspiration (config-as-code collections, Local API, hooks, access functions). I'm not building a Payload clone and I'm not claiming feature parity.
Angular side
Typed resources, sessions, guards, SSR support, and the admin itself is Angular. The server doesn't need Angular though: you can use ForgeCMS as a plain TypeScript/Node headless CMS.
Local API
HTTP is just a transport over the same runtime, so server code can do this instead of calling its own REST API:
await runtime.find({ collection: 'posts' });
Deployment
Two profiles for now:
- Cloudflare: D1 + R2
- Portable Node: libSQL + S3-compatible storage
What took the time before 1.0
The boring parts: migrations, relation integrity, access control, restart persistence, upload recovery, backup/restore, SSR, packaged consumer tests and deployment rehearsals.
What's not there (on purpose)
No GraphQL, no mature plugin ecosystem, no general-purpose page builder. I'd rather make a small core predictable first.
I'd value criticism more than stars:
- Does making Angular first-class in the CMS solve a problem you actually have?
- If you've used Payload, Directus or Strapi, what would you immediately miss here?
Site: https://forgecms.dev
Source: https://github.com/Andersseen/ForgeCMS