vtex-io-app-structure

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

App Architecture & Manifest Configuration

应用架构与Manifest配置

When this skill applies

适用场景

Use this skill when working with the foundational structure of a VTEX IO app — the
manifest.json
file, builder system, policy declarations, dependency management,
service.json
resource limits, and app lifecycle (link, publish, deploy).
  • Creating a new VTEX IO app from scratch
  • Adding a builder to an existing app
  • Configuring policies for API access
  • Troubleshooting deployment failures related to manifest misconfiguration
Do not use this skill for:
  • Backend service implementation details (use
    vtex-io-service-apps
    instead)
  • React component development (use
    vtex-io-react-apps
    instead)
  • GraphQL schema and resolver details (use
    vtex-io-graphql-api
    instead)
当你处理VTEX IO应用的基础结构时可使用本指南,包括
manifest.json
文件、builder系统、策略声明、依赖管理、
service.json
资源限制以及应用生命周期(link、publish、deploy)相关操作:
  • 从零创建新的VTEX IO应用
  • 为现有应用添加builder
  • 配置API访问权限策略
  • 排查因manifest配置错误导致的部署失败问题
请勿将本指南用于以下场景:
  • 后端服务实现细节(请改用
    vtex-io-service-apps
    指南)
  • React组件开发(请改用
    vtex-io-react-apps
    指南)
  • GraphQL schema与解析器细节(请改用
    vtex-io-graphql-api
    指南)

Decision rules

决策规则

  • Every VTEX IO app starts with
    manifest.json
    — it defines identity (
    vendor
    ,
    name
    ,
    version
    ), builders, dependencies, and policies.
  • Use the builder that matches the directory:
    node
    for
    /node
    ,
    react
    for
    /react
    ,
    graphql
    for
    /graphql
    ,
    admin
    for
    /admin
    ,
    pixel
    for
    /pixel
    ,
    messages
    for
    /messages
    ,
    store
    for
    /store
    ,
    masterdata
    for
    /masterdata
    ,
    styles
    for
    /styles
    .
  • Declare policies for every external host your app calls and every VTEX Admin resource it accesses.
  • Use
    service.json
    in
    /node
    to configure memory (max 512MB), timeout, autoscaling, and route definitions.
  • Use semver ranges (
    3.x
    ) for dependencies, not exact versions.
  • Use
    peerDependencies
    for apps that must be present but should not be auto-installed.
Builders reference:
BuilderDirectoryPurpose
node
/node
Backend services in TypeScript (middlewares, resolvers, event handlers)
react
/react
Frontend React components in TypeScript/TSX
graphql
/graphql
GraphQL schema definitions (
.graphql
files)
admin
/admin
Admin panel pages and navigation entries
pixel
/pixel
Pixel/tracking apps that inject scripts into the storefront
messages
/messages
Internationalization — localized string files per locale
store
/store
Store Framework theme blocks, interfaces, and routes
masterdata
/masterdata
Master Data v2 entity schemas and triggers
styles
/styles
CSS/Tachyons configuration for Store Framework themes
Policy types:
  1. Outbound-access policies: Grant access to explicit URLs (external APIs or VTEX endpoints).
  2. License Manager policies: Grant access to VTEX Admin resources using resource keys.
  3. App role-based policies: Grant access to routes or GraphQL queries exposed by other IO apps, using the format
    {vendor}.{app-name}:{policy-name}
    .
Architecture:
text
manifest.json
├── builders → determines which directories are processed
│   ├── node/ → compiled by node builder → backend service
│   ├── react/ → compiled by react builder → frontend bundles
│   ├── graphql/ → compiled by graphql builder → schema/resolvers
│   ├── store/ → compiled by store builder → theme blocks
│   ├── admin/ → compiled by admin builder → admin pages
│   ├── pixel/ → compiled by pixel builder → tracking scripts
│   └── messages/ → compiled by messages builder → i18n strings
├── policies → runtime permissions for API access
├── dependencies → other VTEX IO apps this app requires
└── peerDependencies → apps required but not auto-installed
  • 所有VTEX IO应用都以
    manifest.json
    为起点:它定义了应用身份(
    vendor
    name
    version
    )、builders、依赖以及权限策略。
  • 请使用与目录匹配的builder:
    node
    对应
    /node
    目录、
    react
    对应
    /react
    目录、
    graphql
    对应
    /graphql
    目录、
    admin
    对应
    /admin
    目录、
    pixel
    对应
    /pixel
    目录、
    messages
    对应
    /messages
    目录、
    store
    对应
    /store
    目录、
    masterdata
    对应
    /masterdata
    目录、
    styles
    对应
    /styles
    目录。
  • 请为应用调用的所有外部主机、访问的所有VTEX Admin资源声明对应策略。
  • /node
    目录下使用
    service.json
    配置内存(最大512MB)、超时时间、自动扩缩容以及路由定义。
  • 依赖请使用semver范围(如
    3.x
    ),不要使用精确版本。
  • 对于必须存在但不需要自动安装的应用,请声明在
    peerDependencies
    中。
Builders参考:
Builder目录用途
node
/node
用TypeScript编写的后端服务(中间件、解析器、事件处理器)
react
/react
用TypeScript/TSX编写的前端React组件
graphql
/graphql
GraphQL schema定义(
.graphql
文件)
admin
/admin
管理后台页面与导航入口
pixel
/pixel
向店铺前端注入脚本的像素/追踪应用
messages
/messages
国际化能力:各语言的本地化字符串文件
store
/store
Store Framework主题区块、接口与路由
masterdata
/masterdata
Master Data v2实体schema与触发器
styles
/styles
Store Framework主题的CSS/Tachyons配置
策略类型:
  1. 出站访问策略:授予访问特定URL(外部API或VTEX端点)的权限。
  2. License Manager策略:通过资源密钥授予访问VTEX Admin资源的权限。
  3. 基于应用角色的策略:授予访问其他IO应用暴露的路由或GraphQL查询的权限,格式为
    {vendor}.{app-name}:{policy-name}
架构结构:
text
manifest.json
├── builders → 决定哪些目录会被处理
│   ├── node/ → 由node builder编译 → 后端服务
│   ├── react/ → 由react builder编译 → 前端包
│   ├── graphql/ → 由graphql builder编译 → schema/解析器
│   ├── store/ → 由store builder编译 → 主题区块
│   ├── admin/ → 由admin builder编译 → 管理后台页面
│   ├── pixel/ → 由pixel builder编译 → 追踪脚本
│   └── messages/ → 由messages builder编译 → 国际化字符串
├── policies → API访问的运行时权限
├── dependencies → 本应用依赖的其他VTEX IO应用
└── peerDependencies → 需要存在但不会自动安装的应用

Hard constraints

硬性约束

Constraint: Declare All Required Builders

约束:声明所有需要的Builders

Every directory in your app that contains processable code MUST have a corresponding builder declared in
manifest.json
. If you have a
/node
directory, the
node
builder MUST be declared. If you have a
/react
directory, the
react
builder MUST be declared.
Why this matters
Without the builder declaration, the VTEX IO platform ignores the directory entirely. Your backend code will not compile, your React components will not render, and your GraphQL schemas will not be registered. The app will link successfully but the functionality will silently be absent.
Detection
If you see backend TypeScript code in a
/node
directory but the manifest does not declare
"node": "7.x"
in
builders
, STOP and add the builder. Same applies to
/react
without
"react": "3.x"
,
/graphql
without
"graphql": "1.x"
, etc.
Correct
json
{
  "name": "my-service-app",
  "vendor": "myvendor",
  "version": "1.0.0",
  "title": "My Service App",
  "description": "A backend service app with GraphQL",
  "builders": {
    "node": "7.x",
    "graphql": "1.x",
    "docs": "0.x"
  },
  "dependencies": {},
  "policies": []
}
Wrong
json
{
  "name": "my-service-app",
  "vendor": "myvendor",
  "version": "1.0.0",
  "title": "My Service App",
  "description": "A backend service app with GraphQL",
  "builders": {
    "docs": "0.x"
  },
  "dependencies": {},
  "policies": []
}
Missing "node" and "graphql" builders — the /node and /graphql directories will be completely ignored. Backend code won't compile, GraphQL schema won't be registered. The app links without errors but nothing works.

应用中所有包含可处理代码的目录,必须在
manifest.json
中声明对应的builder。如果你有
/node
目录,必须声明
node
builder;如果你有
/react
目录,必须声明
react
builder。
重要性
如果没有声明对应的builder,VTEX IO平台会完全忽略该目录:你的后端代码不会被编译、React组件不会渲染、GraphQL schema不会被注册。应用可以正常link,但功能会静默缺失。
检测方式
如果你在
/node
目录下看到后端TypeScript代码,但manifest的
builders
中没有声明
"node": "7.x"
,请立即停止操作并添加该builder。同理,如果存在
/react
目录但没有声明
"react": "3.x"
、存在
/graphql
目录但没有声明
"graphql": "1.x"
等情况,都需要补充声明。
正确示例
json
{
  "name": "my-service-app",
  "vendor": "myvendor",
  "version": "1.0.0",
  "title": "My Service App",
  "description": "A backend service app with GraphQL",
  "builders": {
    "node": "7.x",
    "graphql": "1.x",
    "docs": "0.x"
  },
  "dependencies": {},
  "policies": []
}
错误示例
json
{
  "name": "my-service-app",
  "vendor": "myvendor",
  "version": "1.0.0",
  "title": "My Service App",
  "description": "A backend service app with GraphQL",
  "builders": {
    "docs": "0.x"
  },
  "dependencies": {},
  "policies": []
}
缺少"node"和"graphql"builder,/node和/graphql目录会被完全忽略:后端代码不会编译,GraphQL schema不会被注册。应用可以无错误link,但所有功能都无法运行。

Constraint: Declare Policies for All External Access

约束:为所有外部访问声明策略

Every external API call or VTEX resource access MUST have a corresponding policy in
manifest.json
. This includes outbound HTTP calls to external hosts, VTEX Admin resource access, and consumption of other apps' GraphQL APIs.
Why this matters
VTEX IO sandboxes apps for security. Without the proper policy, any outbound HTTP request will be blocked at the infrastructure level, returning a
403 Forbidden
error. This is not a code issue — it is a platform-level restriction.
Detection
If you see code making API calls (via clients or HTTP) to a host, STOP and verify that an
outbound-access
policy exists for that host in the manifest. If you see
licenseManager.canAccessResource(...)
, verify a License Manager policy exists.
Correct
json
{
  "policies": [
    {
      "name": "outbound-access",
      "attrs": {
        "host": "api.vtex.com",
        "path": "/api/*"
      }
    },
    {
      "name": "outbound-access",
      "attrs": {
        "host": "portal.vtexcommercestable.com.br",
        "path": "/api/*"
      }
    },
    {
      "name": "ADMIN_DS"
    },
    {
      "name": "colossus-fire-event"
    },
    {
      "name": "colossus-write-logs"
    }
  ]
}
Wrong
json
{
  "policies": []
}
Empty policies array while the app makes calls to api.vtex.com and uses Master Data. All outbound requests will fail at runtime with 403 Forbidden errors that are difficult to debug.

所有外部API调用或VTEX资源访问,都必须在
manifest.json
中声明对应的策略。包括对外部主机的出站HTTP调用、VTEX Admin资源访问、以及调用其他应用的GraphQL API。
重要性
VTEX IO会对应用做沙箱安全隔离。如果没有正确的策略,所有出站HTTP请求都会在基础设施层被拦截,返回
403 Forbidden
错误。这不是代码问题,而是平台级的限制。
检测方式
如果你看到代码(通过客户端或HTTP方式)调用某个主机的API,请立即停止操作,验证manifest中是否存在对应主机的
outbound-access
策略。如果你看到
licenseManager.canAccessResource(...)
代码,请验证是否存在对应的License Manager策略。
正确示例
json
{
  "policies": [
    {
      "name": "outbound-access",
      "attrs": {
        "host": "api.vtex.com",
        "path": "/api/*"
      }
    },
    {
      "name": "outbound-access",
      "attrs": {
        "host": "portal.vtexcommercestable.com.br",
        "path": "/api/*"
      }
    },
    {
      "name": "ADMIN_DS"
    },
    {
      "name": "colossus-fire-event"
    },
    {
      "name": "colossus-write-logs"
    }
  ]
}
错误示例
json
{
  "policies": []
}
应用需要调用api.vtex.com并使用Master Data,但策略数组为空。所有出站请求都会在运行时返回403 Forbidden错误,排查难度很高。

Constraint: Follow App Naming Conventions

约束:遵守应用命名规范

App names MUST be in kebab-case (lowercase letters separated by hyphens). The vendor MUST match the VTEX account name. Version MUST follow Semantic Versioning 2.0.0.
Why this matters
Apps with invalid names cannot be published to the VTEX App Store. Names with special characters or uppercase letters will be rejected by the builder-hub. Vendor mismatch prevents the account from managing the app.
Detection
If you see an app name with uppercase letters, underscores, special characters, or numbers at the beginning, STOP and fix the name.
Correct
json
{
  "name": "order-status-dashboard",
  "vendor": "mycompany",
  "version": "2.1.3"
}
Wrong
json
{
  "name": "Order_Status_Dashboard",
  "vendor": "mycompany",
  "version": "2.1"
}
Uppercase letters and underscores in the name will be rejected. Version "2.1" is not valid semver — must be "2.1.0".
应用名称必须使用kebab-case格式(小写字母,用连字符分隔)。vendor必须与VTEX账户名一致。版本必须遵守语义化版本2.0.0规范。
重要性
名称不符合规范的应用无法发布到VTEX应用商店。包含特殊字符或大写字母的名称会被builder-hub拒绝。vendor不匹配会导致账户无法管理该应用。
检测方式
如果应用名称包含大写字母、下划线、特殊字符,或者以数字开头,请立即停止操作并修正名称。
正确示例
json
{
  "name": "order-status-dashboard",
  "vendor": "mycompany",
  "version": "2.1.3"
}
错误示例
json
{
  "name": "Order_Status_Dashboard",
  "vendor": "mycompany",
  "version": "2.1"
}
名称中的大写字母和下划线会被拒绝。版本号"2.1"不是有效的语义化版本,必须改为"2.1.0"。

Preferred pattern

推荐模式

Initialize with the VTEX IO CLI:
bash
vtex init
Select the appropriate template:
service-example
,
graphql-example
,
react-app-template
, or
store-theme
.
Recommended manifest configuration:
json
{
  "name": "product-review-service",
  "vendor": "mycompany",
  "version": "0.1.0",
  "title": "Product Review Service",
  "description": "Backend service for managing product reviews with GraphQL API",
  "builders": {
    "node": "7.x",
    "graphql": "1.x",
    "docs": "0.x"
  },
  "dependencies": {
    "vtex.search-graphql": "0.x"
  },
  "policies": [
    {
      "name": "outbound-access",
      "attrs": {
        "host": "api.vtex.com",
        "path": "/api/*"
      }
    },
    {
      "name": "ADMIN_DS"
    },
    {
      "name": "colossus-fire-event"
    },
    {
      "name": "colossus-write-logs"
    }
  ]
}
Recommended
service.json
for backend apps:
json
{
  "memory": 256,
  "timeout": 30,
  "minReplicas": 2,
  "maxReplicas": 10,
  "workers": 4,
  "routes": {
    "reviews": {
      "path": "/_v/api/reviews",
      "public": false
    },
    "review-by-id": {
      "path": "/_v/api/reviews/:id",
      "public": false
    }
  }
}
Recommended directory structure:
text
my-app/
├── manifest.json
├── package.json
├── node/
│   ├── package.json
│   ├── tsconfig.json
│   ├── service.json
│   ├── index.ts          # Service entry point
│   ├── clients/
│   │   └── index.ts      # Client registry
│   ├── middlewares/
│   │   └── validate.ts   # HTTP middleware
│   └── resolvers/
│       └── reviews.ts    # GraphQL resolvers
├── graphql/
│   ├── schema.graphql    # Query/Mutation definitions
│   └── types/
│       └── Review.graphql
├── messages/
│   ├── en.json
│   ├── pt.json
│   └── es.json
└── docs/
    └── README.md
Full
manifest.json
for a comprehensive app using multiple builders:
json
{
  "name": "product-review-suite",
  "vendor": "mycompany",
  "version": "1.0.0",
  "title": "Product Review Suite",
  "description": "Complete product review system with backend, frontend, and admin panel",
  "mustUpdateAt": "2026-01-01",
  "builders": {
    "node": "7.x",
    "react": "3.x",
    "graphql": "1.x",
    "admin": "0.x",
    "messages": "1.x",
    "store": "0.x",
    "docs": "0.x"
  },
  "dependencies": {
    "vtex.styleguide": "9.x",
    "vtex.store-components": "3.x",
    "vtex.css-handles": "0.x"
  },
  "peerDependencies": {
    "vtex.store": "2.x"
  },
  "policies": [
    {
      "name": "outbound-access",
      "attrs": {
        "host": "api.vtex.com",
        "path": "/api/*"
      }
    },
    {
      "name": "ADMIN_DS"
    },
    {
      "name": "colossus-fire-event"
    },
    {
      "name": "colossus-write-logs"
    }
  ],
  "settingsSchema": {
    "title": "Product Review Suite Settings",
    "type": "object",
    "properties": {
      "enableModeration": {
        "title": "Enable review moderation",
        "type": "boolean"
      },
      "reviewsPerPage": {
        "title": "Reviews per page",
        "type": "number"
      }
    }
  }
}
使用VTEX IO CLI初始化项目:
bash
vtex init
选择合适的模板:
service-example
graphql-example
react-app-template
store-theme
推荐的manifest配置:
json
{
  "name": "product-review-service",
  "vendor": "mycompany",
  "version": "0.1.0",
  "title": "Product Review Service",
  "description": "Backend service for managing product reviews with GraphQL API",
  "builders": {
    "node": "7.x",
    "graphql": "1.x",
    "docs": "0.x"
  },
  "dependencies": {
    "vtex.search-graphql": "0.x"
  },
  "policies": [
    {
      "name": "outbound-access",
      "attrs": {
        "host": "api.vtex.com",
        "path": "/api/*"
      }
    },
    {
      "name": "ADMIN_DS"
    },
    {
      "name": "colossus-fire-event"
    },
    {
      "name": "colossus-write-logs"
    }
  ]
}
推荐的后端应用
service.json
配置:
json
{
  "memory": 256,
  "timeout": 30,
  "minReplicas": 2,
  "maxReplicas": 10,
  "workers": 4,
  "routes": {
    "reviews": {
      "path": "/_v/api/reviews",
      "public": false
    },
    "review-by-id": {
      "path": "/_v/api/reviews/:id",
      "public": false
    }
  }
}
推荐的目录结构:
text
my-app/
├── manifest.json
├── package.json
├── node/
│   ├── package.json
│   ├── tsconfig.json
│   ├── service.json
│   ├── index.ts          # 服务入口文件
│   ├── clients/
│   │   └── index.ts      # 客户端注册
│   ├── middlewares/
│   │   └── validate.ts   # HTTP中间件
│   └── resolvers/
│       └── reviews.ts    # GraphQL解析器
├── graphql/
│   ├── schema.graphql    # Query/Mutation定义
│   └── types/
│       └── Review.graphql
├── messages/
│   ├── en.json
│   ├── pt.json
│   └── es.json
└── docs/
    └── README.md
使用多个builder的完整应用
manifest.json
示例:
json
{
  "name": "product-review-suite",
  "vendor": "mycompany",
  "version": "1.0.0",
  "title": "Product Review Suite",
  "description": "Complete product review system with backend, frontend, and admin panel",
  "mustUpdateAt": "2026-01-01",
  "builders": {
    "node": "7.x",
    "react": "3.x",
    "graphql": "1.x",
    "admin": "0.x",
    "messages": "1.x",
    "store": "0.x",
    "docs": "0.x"
  },
  "dependencies": {
    "vtex.styleguide": "9.x",
    "vtex.store-components": "3.x",
    "vtex.css-handles": "0.x"
  },
  "peerDependencies": {
    "vtex.store": "2.x"
  },
  "policies": [
    {
      "name": "outbound-access",
      "attrs": {
        "host": "api.vtex.com",
        "path": "/api/*"
      }
    },
    {
      "name": "ADMIN_DS"
    },
    {
      "name": "colossus-fire-event"
    },
    {
      "name": "colossus-write-logs"
    }
  ],
  "settingsSchema": {
    "title": "Product Review Suite Settings",
    "type": "object",
    "properties": {
      "enableModeration": {
        "title": "Enable review moderation",
        "type": "boolean"
      },
      "reviewsPerPage": {
        "title": "Reviews per page",
        "type": "number"
      }
    }
  }
}

Common failure modes

常见失败场景

  • Declaring unused builders: Adding builders "just in case" creates overhead during the build process. Unused builder directories can cause build warnings. Only declare builders your app actively uses.
  • Wildcard outbound policies: Using
    "host": "*"
    or
    "path": "/*"
    is a security risk, will be rejected during app review, and makes security audits difficult. Declare specific policies for each external service.
  • Hardcoding version in dependencies: Pinning exact versions like
    "vtex.store-components": "3.165.0"
    prevents receiving bug fixes. Use major version ranges with
    x
    wildcard:
    "vtex.store-components": "3.x"
    .
  • 声明未使用的builders:“以防万一”添加多余的builder会增加构建过程的开销,未使用的builder目录还会导致构建警告。请仅声明应用实际使用的builder。
  • 通配符出站策略:使用
    "host": "*"
    "path": "/*"
    存在安全风险,会在应用审核时被拒绝,也会增加安全审计的难度。请为每个外部服务声明具体的策略。
  • 依赖硬编码版本:固定精确版本比如
    "vtex.store-components": "3.165.0"
    会导致无法收到bug修复。请使用带
    x
    通配符的大版本范围:
    "vtex.store-components": "3.x"

Review checklist

审核检查清单

  • Does every code directory (
    /node
    ,
    /react
    ,
    /graphql
    , etc.) have a matching builder in
    manifest.json
    ?
  • Are all external hosts and VTEX resources declared in
    policies
    ?
  • Is the app name kebab-case, vendor matching account, version valid semver?
  • Does
    service.json
    exist for apps with the
    node
    builder?
  • Are dependencies using major version ranges (
    3.x
    ) instead of exact versions?
  • Are placeholder values (vendor, app name, policies) replaced with real values?
  • 所有代码目录(
    /node
    /react
    /graphql
    等)都在
    manifest.json
    中有匹配的builder吗?
  • 所有外部主机和VTEX资源都在
    policies
    中声明了吗?
  • 应用名称是kebab-case格式、vendor与账户匹配、版本是有效的语义化版本吗?
  • 使用
    node
    builder的应用存在
    service.json
    文件吗?
  • 依赖使用的是大版本范围(
    3.x
    )而不是精确版本吗?
  • 占位值(vendor、应用名称、策略)都替换为真实值了吗?

Reference

参考资料

  • Manifest — Complete reference for all manifest.json fields and their usage
  • Builders — Full list of available builders with descriptions and usage examples
  • Policies — How to declare outbound-access, License Manager, and role-based policies
  • Dependencies — Managing app dependencies and peer dependencies
  • Accessing External Resources — Policy types and patterns for external API access
  • Creating a New App — Step-by-step guide for app initialization
  • Manifest — manifest.json所有字段的完整参考与用法
  • Builders — 所有可用builder的完整列表,包含说明与使用示例
  • Policies — 如何声明出站访问、License Manager以及基于角色的策略
  • Dependencies — 管理应用依赖与peer依赖
  • 访问外部资源 — 外部API访问的策略类型与模式
  • 创建新应用 — 应用初始化的分步指南