# A config-as-code CMS in Go

> Evaluate Ridu for Payload-style content modeling and PocketBase-style single-binary deployment, with Go access rules, hooks, computed fields, and blocks.

Canonical URL: https://riducms.com/guides/config-as-code-cms/

Ridu is an open-source, config-as-code backend framework for Go with a headless CMS built in.
Define collections, fields, access rules, hooks, and plugins in Go; give editors a Svelte admin;
deploy the API and built admin together as one Go binary.

If you are looking for a CMS that combines Payload's approach to content modeling with
PocketBase's single-executable deployment, Ridu is worth evaluating. The comparison describes
its direction; the practical fit depends on the authoring features and deployment your project
needs.

## Keep the content model in code {#config-as-code}

Config as code means your application's source files define the content model and its behavior.
In Ridu, an ordinary Go function returns `ridu.Config`. You can compose fields with functions,
reuse access rules across collections, and test changes before deploying them. Editors create
and update content in the admin; developers change the schema through code review.

The configuration is executable. Ridu runs your project to resolve it, so Go helpers and plugin
constructors participate in building the model. Access callbacks, hooks, and computed-field
resolvers remain Go functions that run on the server when content is used.

From that configuration, Ridu generates a schema manifest, reviewable migrations, OpenAPI,
Go models, and TypeScript contracts. The same model supplies the admin's forms and the
generated Fetch SDK. You maintain the Go source and regenerate these artifacts when it changes.
See [Configuration](https://riducms.com/docs/configuration/), [Core concepts](https://riducms.com/docs/core-concepts/), and
[Generated contracts](https://riducms.com/docs/generated-contracts/) for the complete development loop.

Headless means the CMS serves content to your application through APIs. Your public website or
app can use its own frontend framework; the Svelte admin is the editing interface supplied by
Ridu.

## Compare the Payload and PocketBase models {#payload-and-pocketbase}

[Payload's configuration](https://payloadcms.com/docs/configuration/overview) puts its content
model and application behavior in JavaScript or TypeScript. Its
[fields](https://payloadcms.com/docs/fields/overview) support validation, access rules, hooks,
and virtual values. Ridu follows a similar approach to authoring a CMS, using Go configuration
and Svelte admin components. The [Payload guide](https://riducms.com/guides/from-payload/#configuration) compares
complete collection definitions and ownership rules side by side.

[PocketBase](https://pocketbase.io/docs/) combines SQLite, authentication, a dashboard, APIs,
and realtime subscriptions in a portable backend. Its
[collections](https://pocketbase.io/docs/collections/) can be managed from the dashboard, APIs,
or code, and it supports [Go event hooks](https://pocketbase.io/docs/go-event-hooks/).
Ridu shares the appeal of deploying one executable while making executable content
configuration and editorial workflows central to the application.

Choose between these approaches based on how your team wants to model content, extend the
editor, and run the backend. The [PocketBase guide](https://riducms.com/guides/from-pocketbase/) covers the
differences in schema management, databases, realtime behavior, and migration.

## Check the authoring features you need {#features}

Ridu's content model includes the following server behavior and editing tools. Each link
leads to configuration examples and the feature's limits.

| Requirement                                                 | How it works in Ridu                                                                                                                            |
| ----------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| [Access control](https://riducms.com/docs/access-control/)                     | Go rules protect collections, globals, and individual fields. Filtered document rules apply within the database operation.                      |
| [Hooks](https://riducms.com/docs/hooks/)                                       | Field, collection, and global hooks run Go code during content operations. Use after-commit hooks for effects that depend on a successful save. |
| [Computed fields](https://riducms.com/docs/fields/virtual/)                    | Virtual fields calculate read-only output in Go. They appear in responses and generated output types without a stored column.                   |
| [Blocks](https://riducms.com/docs/fields/blocks/)                              | Authors combine configured content sections, edit their fields, and reorder them. Each block type has its own schema.                           |
| [Drafts and versions](https://riducms.com/docs/drafts-and-versions/)           | Enable revision history, draft visibility, publishing, restore, and scheduled collection changes.                                               |
| [Rich text](https://riducms.com/docs/rich-text/) and [uploads](https://riducms.com/docs/uploads/) | Add structured rich text and media collections to the editing workflow.                                                                         |
| [Custom admin components](https://riducms.com/docs/custom-components/)         | Register Svelte inputs, views, and other supported extension points.                                                                            |

Access checks, validation, and hooks apply through the admin, REST, the generated SDK, and
the local Go API. A server-side call uses the same rules as other content operations.

Computed output has a specific boundary: virtual fields belong at a collection or global root
and cannot be filtered or sorted in the database. Use a stored field and a write hook when a
calculated value must support those queries.

## Match the deployment to your workload {#deployment}

`ridu build` embeds the compiled admin and server extensions in the Go executable. JavaScript
tooling is used during development and the build; production does not need a Node or Bun
server. Database files or services and uploaded objects still need persistent storage.

Use [PostgreSQL](https://riducms.com/docs/postgres/) for networked, multi-host deployments, or
[SQLite](https://riducms.com/docs/sqlite/) for small or local workloads using a file on one application host.
[MongoDB](https://riducms.com/docs/mongodb/) has a narrower supported production profile; check its deployment
requirements before choosing it.

Ridu has its own APIs and plugin contracts. Payload access rules and hooks need Go rewrites,
and React admin components need Svelte replacements. General PocketBase-style realtime
subscriptions and a PocketBase importer are not supported. Ridu's
[live preview](https://riducms.com/guides/live-preview/) covers a narrower editorial use case.

## Evaluate one content workflow {#get-started}

Start with [Installation](https://riducms.com/docs/installation/) and model one collection your editors actually
use. Add its permissions, a lifecycle hook, and a block layout; then create, publish, and read
that content through your frontend. Use the [TypeScript SDK](https://riducms.com/docs/typescript-sdk/) or
[local Go API](https://riducms.com/docs/local-api/) to exercise the same behavior outside the admin.

Check [Capability status](https://riducms.com/docs/status/) for the remaining requirements before planning a
migration. If you know Payload already, [Move from Payload](https://riducms.com/guides/from-payload/) is the next
step; for an existing PocketBase application, start with
[Coming from PocketBase](https://riducms.com/guides/from-pocketbase/).
