TypeScript icon, indicating that this package has built-in type declarations

5.5.3 • Public • Published

JvM Contentful Migrations

NPM Version Sonarcloud Status

JvM Contentful Migrations offers additional functionality on top of the existing migration functionality of the Contentful CLI. It makes it easy and safe to deploy changes to your content model in a way that can be reviewed and tested before being deployed to production. With migrations you can do almost everything with your content and your content model. See the official documentation for more information.

Getting started


npm i @jungvonmatt/contentful-migrations


After installation we only need a few bits of information to get you started. To help you configure contentful-migrations just run the init command.

npx migrations init

This initializes migrations and stores the config values in the package.json or the .migrationsrc file.

You can also use this command if you want to switch from managing migrations in Contentful with a single Tag to the recommended approach using a dedicated Content type for migrations

Configuration files

The default configuration file name is .migrationsrc. But since we use cosmiconfig you can also use the other supported config file formats and name patterns like migrationsrc.json or migrations.config.js.

You can also use any config file path by adding the -f <path/to/confg> or --config-file <path/to/config> command line argument. The extensions .json, .yaml, .yml, .js, or .cjs are supported.

By specifying the config file path you can use multiple config files for different environments or spaces in your project.

Configuration values

Name Default Description
accessToken undefined Contentful Management Token. Just run npx contentful login and you're done.
spaceId undefined Contentful Space id. Will fallback to process.env.CONTENTFUL_SPACE_ID if not set.
environmentId undefined Contentful Environment id. Will fallback to process.env.CONTENTFUL_ENVIRONMENT_ID if not set.
If neither environmentId nor CONTENTFUL_ENVIRONMENT_ID is available we search for environment whose id matches the current git branch
requestBatchSize undefined The batch size used for loading data from contentful. Contentful uses a default of 100. Use a smaller value when you get Response size too big errors (for example caused by very large rich text fields). Be aware that contentful migrations might hide the response size error and only print The provided space does not exist or you do not have access
storage undefined We need to keep a hint to the executed migrations inside Contentful. You can choose between *content and tag.

Content will add a new content type to your Contentful environment and stores the state of every migration as content entry (recommended approach)
tag Will only store the latest version inside a tag. You need to preserve the right order yourself. When you add a new migration with an older version number it will not be executed.
fieldId 'migration' Id of the tag where the migration version is stored (only used with storage tag)
migrationContentTypeId 'contentful-migrations' Id of the migration content-type (only used with storage content)
directory './migrations' Directory where the migration files are stored

Showing help

Whenever you get stuck, you can output the help to your terminal:

npx migrations help

# Help for a specific command
npx migrations help <command>

Handling contentful environments

It is recommended that you develop and test your migrations in a separate environment before executing them on production content. You can handle environments using the environment command:

# Add a new environment and activate it for API usage
npx migrations environment <environment-id> --create [--source-environment-id <source-environment-id>]

# Remove an environment
npx migrations environment <environment-id> --remove [--source-environment-id <source-environment-id>]

# Reset an environment
npx migrations environment <environment-id> --reset [--source-environment-id <source-environment-id>]

Generating blank migrations

To generate a blank migration you can use the generate command:

npx migrations generate

Generate a migration from an existing content-type

Sometimes you may not want to start a migration from scratch. You can create a new Content type in the contentful web app and import it using the fetch command.

When you want to use the contentful web app to configure your content types you should do so in a separate environment because the migration will fail if the content-type is already present at the time you run the migration script

# Generate migration scripts for all content types from the current environment
npx migrations fetch

# Generate migration scripts only for specific content types from the current environment
npx migrations fetch -c <content-type> -c <another-content-type>

# Generate migration script for single content type from a custom environment
npx migrations fetch -c <content-type> -e <environment-id>

Executing multiple migrations

You can execute all "new" migrations using the migrate command.

# Run all 'new' migrations in the current environment
npx migrations migrate

# Run all 'new' migrations in a custom environment
npx migrations migrate -e <environment-id>

Executing single migrations

You may want to just execute a single migration. You can do this with the execute command:

# Execute single migration in the current environment
npx migrations execute <path/to/migration.js>

# Execute single migration in a custom environment
npx migrations execute <path/to/migration.js> -e <environment-id>

Managing the migration versions stored in contentful

Sometimes you may need to manually mark a migration as migrated or not. You can use the version command for this. Use caution when using the version command. If you delete a version from the table and then run the migrate command, that migration version will be executed again.

This command is only available when using the content storage

# Add a migration entry to Contentful
npx migrations version <path/to/migration.js> --add

# Delete a migration entry from Contentful
npx migrations version <path/to/migration.js> --remove

# Add a migration entry to Contentful in a custom environment
npx migrations version <path/to/migration.js> --add -e <environment-id>

# Delete a migration entry from Contentful in a custom environment
npx migrations version <path/to/migration.js> --remove -e <environment-id>

Migrating content between environments

In some workflows it may be required to create and test content in a dedicated environment and 'copy' it after an approval process to your production environment. You can do this using the content command.

# Transfer content from one Contentful environment to another.
# This command will not overwrite existing content unless you say so.
npx migrations content --source-environment-id <environment>  --dest-environment-id <environment>
Optional Arguments

--content-type: Limit to specific content-type and it's dependencies.
--diff: Manually choose skip/overwrite for every conflicting content.
--force: No manual diffing. Overwrites all conflicting entries/assets.
--verbose: Show tree of entries/assets which should be migrated.

Diff example

Generating documentation for your content types

You may want to have some markdown documentation for your content-types. With the doc command you can auto-generate the documentation. You can use the default template or you can specify a custom template using either a Javascript file or a mustache template.

npx migrations doc -e <environment> -p <path/to/docs>
Optional Arguments

--template: Use a custom template for docs. .js with default export or .mustache is allowed
--extension: Use a custom file extension (default is .md)

Migration helpers

We provide you with a few smaller migration helpers. There aren't many at the moment, but there may be more in the future.

To use the helpers you just need to wrap your migration with the provided withHelpers function which makes the helpers available as 3rd parameter in your migration function:

const { withHelpers } = require('@jungvonmatt/contentful-migrations');

module.exports = withHelpers(async (migration, context, helpers) => {
  // Get all locales
  await helpers.locale.getLocales();
  // Get default locale
  await helpers.locale.getDefaultLocale();

  // Add or remove values from "linkContentType" validations without knowing all the other elements in the array
  await helpers.validation.addLinkContentTypeValues('contentTypeId', 'fieldId', ['some-content-type']);
  await helpers.validation.removeLinkContentTypeValues('contentTypeId', 'fieldId', ['some-content-type']);
  await helpers.validation.modifyLinkContentTypeValues('contentTypeId', 'fieldId', (existing) => {
    const result = existing.filter((contentType) => !contentType.startsWith('a-')); // remove some by prefix
    result.push('t-test'); // and add one
    return result; // possible duplicate values are removed afterwards

  // Add or remove values from "in" validations without knowing all the other elements in the array
  await helpers.validation.addInValues('contentTypeId', 'fieldId', ['value']); // add at the end
  await helpers.validation.addInValues('contentTypeId', 'fieldId', ['value'], { mode: 'sorted'}); // add and sort
  await helpers.validation.removeInValues('contentTypeId', 'fieldId', ['value']);
  await helpers.validation.modifyInValues('contentTypeId', 'fieldId', (existing) => {
    const result = existing.filter((value) => value.startsWith('prefix')); // keep values with prefix
    result.push('other'); // and add one
    return result; // possible duplicate values are removed afterwards


Can I contribute?

Of course. We appreciate all of our contributors and welcome contributions to improve the project further. If you're uncertain whether an addition should be made, feel free to open up an issue and we can discuss it.


Package Sidebar


npm i @jungvonmatt/contentful-migrations

Weekly Downloads






Unpacked Size

108 kB

Total Files


Last publish


  • jvm-tech
  • peter.klostermann
  • bezoerb
  • sebil