BTST
PluginsQuickstartDocs
Live Blog

From research to product evaluation

Evaluating a publishing workflow for an app you already own?

See what the BTST Blog plugin adds to an existing React or Next.js app
BTST

Open-source TypeScript features for the React application, data, and deployment you already own.

Released plugins

  • Blog
  • AI Chat
  • CMS
  • Form Builder
  • UI Builder
  • Kanban
  • Comments
  • Media
  • Route Docs
  • OpenAPI
  • Better Auth UI

Resources

  • Quickstart
  • Documentation
  • All plugins
  • Live Blog
  • GitHub (opens in a new tab)
© 2026 BTST. Open source under the MIT License.
AI Chat
September 10, 2026ReactBlogCMS

Blog or CMS for a React App? Choose by Your Content Model

Compare a post-oriented publishing workflow with developer-defined CMS models, using concrete content examples and an editorial trial.

Blog or CMS for a React App? Choose by Your Content Model

Your React application needs content editing. The first decision is not which editor looks better; it is whether your content already fits a publishing model or needs a model your developers define.

BTST offers both Blog and CMS inside an existing application. Blog supplies a post-oriented publishing workflow. CMS supplies typed content models and editorial tools for those models. Choosing between them becomes easier when you describe the first real content item and the public page that will display it.

Start with one concrete content item#

Consider two requests from the same product team.

“Marketing needs to publish tutorials with a title, excerpt, body, tags, and a stable article URL.” That request fits a Blog. The team wants a familiar draft-to-published workflow and public article pages.

“The product needs an integration directory with provider names, setup URLs, categories, availability, and a relationship to supported products.” That is structured application content. Its fields and public display rules should come from a deliberate content model.

Both involve text editing. They differ in what the stored record means and which workflow the application must supply.

RequirementStart by evaluating
Posts, drafts, publication, tags, article pagesBlog
Developer-defined content types and fieldsCMS
A custom public directory or detail viewCMS plus application rendering
Runtime form design and submitted responsesForm Builder
Visual page composition from registered componentsUI Builder over CMS

This table is a starting point, not a requirement to install every related plugin. Choose the smallest feature boundary that handles the real job.

What choosing Blog gives you#

BTST Blog owns a recognizable set of post data, operations, editor views, and public routes. It includes draft and publishing behavior, tags, and metadata integration. The Blog evaluator describes its released boundary, while the Blog reference documents configuration.

You still own the database, deployment, access policy, and framework integration. Public pages must use the correct site origin and published-content boundary. Production storage should survive process restarts; an in-memory demonstration is useful for evaluation, not durable editorial storage.

Blog is a good fit when a new content requirement can be expressed as another post. Be cautious when every new request adds a special field or conditional rendering rule that has little to do with publishing. A pricing tier, vendor record, or product compatibility matrix may deserve its own model.

What choosing CMS asks you to define#

With CMS, developers define content types using Zod schemas. The schema describes fields and validation; the generated editorial UI lets authorized users manage content of that type. The CMS evaluator describes that distinction from Blog and Form Builder.

For example, this schema expresses an integration-directory record. It demonstrates the data model only; it is not a complete CMS registration or a public page:

TS
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
import { z } from "zod";

export const IntegrationSchema = z.object({
  name: z.string().trim().min(1),
  summary: z.string().trim().min(1).max(240),
  setupUrl: z.url(),
  category: z.enum(["analytics", "storage", "email"]),
});

Now the application can reject a missing name or an unknown category consistently. Use the CMS configuration reference to register a content type and connect its management UI. Your application still decides how a public integration page looks, which records visitors may read, and how URLs and metadata are produced.

A generated content form does not by itself define a public publishing lifecycle. If the product needs drafts, review, scheduled release, or tenant-specific visibility, establish which behavior exists in the selected feature and which behavior your application must implement. Do not assume a field named published creates a complete authorization or scheduling system.

Use both when the records have different jobs#

A product site may use Blog for tutorials and CMS for an integration directory. That is a reasonable separation because the records have different meanings and public views. Link related records through a stable identifier or URL appropriate to your application rather than copying the same long description into both systems.

Keep ownership clear. A tutorial may explain how to configure an integration; the directory entry can remain the maintained source for its setup link and category. Decide which page should answer a searcher's question so that the two pages complement each other.

Run a small editorial trial#

Before extending the data model, create one representative item in a development environment. Have the intended editor perform the actual workflow: enter the fields, correct an invalid value, save a draft or record, preview the result where supported, and make it available through your chosen public process.

Then change a field that matters. Does an article title update its card and metadata? Does an invalid directory category get rejected? Can an ordinary visitor see a private record? These checks reveal missing application responsibilities earlier than a broad feature checklist.

If the content is ordinary publication, begin with Blog installation. If the record needs a developer-defined structure, begin with CMS. Both fit the maintained Next.js, TanStack Start, and React Router integrations; the decisive difference is the content and workflow your application needs to own.

In This Post

Start with one concrete content itemWhat choosing Blog gives youWhat choosing CMS asks you to defineUse both when the records have different jobsRun a small editorial trial