DEV Community

Cover image for I built a local Contentful model simulator to stop testing content models blindly
Joshua Pozos
Joshua Pozos

Posted on

I built a local Contentful model simulator to stop testing content models blindly

When you work with Contentful long enough, you start noticing how much model work is still too easy to do blindly.

You change a field, push it, inspect it in a real space, realize something is off, undo it, tweak it again, and repeat. It gets worse when you are planning a migration and you cannot really see how the content will look until you import it into Contentful and deal with the fallout there. That loop is slow, clumsy, and riskier than it should be.

That is why I started building content-model-simulator.

It is not finished yet. This is still a work in progress. But v0.3.0 is already out, and my target is to reach v1.0.0 by the end of May. The point of this post is not to pretend the tool is done. The point is to show the problem I am trying to solve, what already works, and what I have learned while building it.

Content browser showing entries list, field panel, and a linked reference

The problem

I do not like testing content models directly in a real Contentful space unless I absolutely have to.

For simple changes, maybe that is fine. But once the model starts getting more connected, localized, or migration-heavy, working directly against a live space becomes awkward. You are not really designing anymore. You are poking the system and hoping the shape in your head matches the shape in the CMS.

And the pain is not only about content types.

It is also about:

  • seeing how entries will actually look
  • spotting broken assumptions before import
  • validating references
  • checking how localized content behaves
  • understanding whether an existing migration script really produces the model you think it does

That is the gap I wanted to attack.

What I am building

content-model-simulator is a local-first simulator for Contentful content models.

The core idea is simple: define schemas locally, point the tool at real data or mock data, and inspect the result in a browser before touching your real Contentful space. The project is explicitly positioned as a simulation tool, not a migration runner, and its README is pretty clear about that boundary.

Today, it already supports things like:

  • offline simulation of content types, entries, references, and validation errors
  • a Content Browser UI to inspect entries and follow references
  • a Content Model Graph to visualize relationships
  • mock data generation for designing from scratch
  • pulling a content model from Contentful for local preview
  • migration preview from external sources like WordPress XML or Sanity NDJSON
  • CI-friendly validation
  • converting existing contentful-migration scripts into local schemas with from-migrations, which landed in v0.3.0

Content model graph with multiple content types and relationships

Why I built it this way

I did not want another tool that only sounded useful in theory.

I wanted something that matched a real workflow:

  1. define or pull a model
  2. inspect it locally
  3. preview entries
  4. validate the structure
  5. reduce the chance of breaking something once the real migration or implementation starts

That is the part I care about most: reducing stupid risk before it reaches a real space.

In other words, this is less about “look, I built a package” and more about “I am trying to make Contentful model work less fragile.”

What v0.3.0 already gave me

The new piece in v0.3.0 that I am especially happy about is from-migrations.

A lot of teams already use contentful-migration files as the source of truth for their models. So instead of forcing people to manually rewrite that thinking into another format, I wanted a way to convert migration scripts into simulator schemas and preview them locally. The current changelog describes from-migrations as a subcommand that converts contentful-migration scripts into cms-sim schema files without needing a Contentful connection.

That matters because it moves the tool closer to a real engineering workflow, not just a demo workflow.

# Convert your existing contentful-migration files to cms-sim schemas
npx cms-sim from-migrations --migrations=./migrations/ --output=./schemas/

# Preview the resulting content model locally
npx cms-sim --schemas=./schemas/ --open
Enter fullscreen mode Exit fullscreen mode

If your migration files are TypeScript:

npx tsx $(which cms-sim) from-migrations --migrations=./migrations/ --output=./schemas/
Enter fullscreen mode Exit fullscreen mode

What it is not

This tool does not replace Contentful.

It does not upload, create, or modify anything in your space during simulation. It does not run the actual migration for you either. The package README is explicit: this is a simulator, not a migration tool. The goal is to help you inspect, validate, and think more clearly before you use Contentful’s own tooling for the real operation.

That distinction matters. I would rather be precise than oversell it.

What I learned while building it

A few things became obvious once I started building this.

1. Content modeling is not only structure, it is behavior

It is easy to think a content model is just fields and types. It is not.

The real pain appears when you factor in references, locales, validation rules, migration paths, editor expectations, and how actual content will sit inside the model. A model can look fine on paper and still be terrible in practice.

2. Preview changes how you think

The moment you can inspect entries and relationships locally, the conversation changes.

You stop arguing only at the schema level. You start noticing editorial friction, broken assumptions, weird relationships, and validation gaps earlier. That is where the value is.

3. Existing migration scripts are too valuable to ignore

If a team already invested in contentful-migration, that work should not be trapped in a one-way execution path. Being able to extract value from those scripts for local preview feels like the right direction.

Quick example of the intended workflow

This is the kind of loop I want the tool to support:

# Install
npm install content-model-simulator

# Scaffold a new project with example schemas
npx cms-sim init

# Simulate and open the Content Browser
npx cms-sim --schemas=schemas/ --open
Enter fullscreen mode Exit fullscreen mode

Then, once you already have migration scripts:

# Convert contentful-migration files → local schemas
npx cms-sim from-migrations --migrations=./migrations/ --output=./schemas/

# Preview without touching Contentful
npx cms-sim --schemas=./schemas/ --open
Enter fullscreen mode Exit fullscreen mode

And if you are working with an existing Contentful space:

# Pull the content model from your space (read-only, CDA token)
npx cms-sim pull --space-id=YOUR_SPACE_ID --access-token=YOUR_CDA_TOKEN

# Simulate locally against the pulled schemas
npx cms-sim --schemas=./pulled/schemas/ --open
Enter fullscreen mode Exit fullscreen mode

What is still missing

A lot.

This is still pre-1.0 work, and I do not want to fake maturity where it does not exist.

There is still polish to do. There are still workflow edges to improve. There is still room to make the UX sharper, the docs tighter, and the tool more battle-ready for bigger real-world cases.

That is exactly why I am sharing it now.

I like build-in-public when it is honest. Not “look at my perfect tool,” but “here is the problem, here is the current state, here is the direction.”

Why I am posting this now

Because I think Contentful teams deserve better tooling around model design, migration preview, and validation.

And because I want to contribute something useful to that space while I am still learning from the build itself.

So this is where the project stands today:

  • current version: v0.3.0
  • status: still in progress
  • goal: v1.0.0 by the end of May

If you work with Contentful and this problem sounds familiar, feel free to take a look, break it, question it, or tell me where the current workflow still feels weak.

That feedback is more useful to me than fake applause.

content-model-simulator v0.3.0

Repo: github.com/JoshuaPozos/content-model-simulator
Package: npmjs.com/package/content-model-simulator

Top comments (0)