Upgrading Strapi v4 to Strapi v5
Strapi v5 is a major update with breaking changes. Main changes: new API response format (flat structure instead of data.attributes), new Document Service instead of Entity Service, updated TypeScript.
Key Changes
API Response Format:
// Strapi v4
{
"data": {
"id": 1,
"attributes": { "title": "Article", "slug": "article" }
}
}
// Strapi v5
{
"id": 1,
"documentId": "abc123",
"title": "Article",
"slug": "article"
}
Document Service instead of Entity Service:
// v4 (Entity Service)
await strapi.entityService.findMany('api::article.article', {
filters: { published: true },
populate: ['author'],
})
// v5 (Document Service)
await strapi.documents('api::article.article').findMany({
filters: { published: true },
populate: ['author'],
})
Draft/Publish via status instead of publishedAt:
// v4
{ filters: { publishedAt: { $notNull: true } } }
// v5
{ status: 'published' }
Official Migration Tool
# Update Strapi
npx @strapi/upgrade major
# Or step-by-step:
npm install @strapi/strapi@5 @strapi/plugin-graphql@5 # and other plugins
# Run codemods for automatic changes
npx @strapi/codemods migrate
Codemods will automatically update:
- Entity Service → Document Service
- Deprecated lifecycle hooks
- Imports from
@strapi/strapi
Frontend Update
Frontend needs to be updated for the new response format:
// Before (v4)
const getTitle = (data: any) => data.attributes.title
// After (v5)
const getTitle = (data: any) => data.title
// Or create compatibility layer:
function flattenStrapiData<T>(item: { id: number; attributes: T }): T & { id: number } {
return { id: item.id, ...item.attributes }
}
If frontend is large — can enable compatibility mode in v5:
// config/features.js
module.exports = { contentReleasesEnabled: true }
// Or via env:
STRAPI_RESPONSE_ENVELOPE=true // returns v4-compatible format
Update Order
- Update Strapi in staging environment
- Run
npx @strapi/codemods migrateon server code - Run API tests — find places with changed format
- Update frontend for new format
- Test full site
- Deploy to production with maintenance window
Plugin Compatibility Check
# Check all plugins for v5 compatibility
npm ls | grep strapi
# For each plugin check: https://market.strapi.io
Some community plugins may not have v5 versions — need to find alternatives or wait for updates.
Timeline
Mid-project migration (5–8 content types, custom controllers, frontend) — 3–5 days provided frontend isn't huge.







