npx skills add ...
npx skills add vtex/skills --skill vtex-io-data-access-patterns
Apply when deciding where and how a VTEX IO app should store and read data. Covers when to use app settings, configuration apps, Master Data, VBase, VTEX core APIs, or external stores, and how to avoid duplicating sources of truth or abusing configuration stores for operational data. Use for new data flows, caching decisions, refactors, or reviewing suspicious storage and access patterns in VTEX IO apps.
npx skills add vtex/skills --skill vtex-io-data-access-patterns
Use this skill when the main question is where data should live and how a VTEX IO app should read or write it.
Do not use this skill for:
AUTH_TOKEN, STORE_TOKEN, or manifest permissionsApp settings and configuration apps MUST represent configuration, not transactional records, unbounded lists, or frequently changing operational state.
Why this matters
Using configuration stores as data storage blurs system boundaries, makes workspace behavior harder to reason about, and breaks expectations for tools and flows that depend on settings being small and stable.
Detection
If you see arrays of records, logs, histories, orders, or other growing operational payloads inside settingsSchema, configuration app payloads, or settings-related APIs, STOP and move that data to Master Data, VBase, a core API, or an external store.
Correct
Wrong
VTEX core systems such as Orders, Catalog, Pricing, and Logistics MUST remain the primary source of truth for their own business domains.
Why this matters
Treating a local IO copy as the main store for core domains creates reconciliation drift, stale reads, and business decisions based on outdated data.
Detection
If an app stores full order payloads, product documents, inventory snapshots, or price tables in Master Data or VBase and then uses those copies as the main source for business decisions, STOP and redesign the flow around the authoritative upstream source.
Correct
Wrong
Large or growing datasets MUST be accessed through bounded queries, filters, pagination, or precomputed derived views instead of full scans and broad in-memory filtering.
Why this matters
Unbounded reads are inefficient, hard to scale, and easy to turn into fragile service behavior as the dataset grows.
Detection
If you see code that fetches entire collections from Master Data, VTEX APIs, or external stores and then filters or aggregates the result in Node for a normal request flow, STOP and redesign the access path.
Correct
Wrong
Start every data design with four questions:
Then choose intentionally:
If the app stores a local copy, keep it small, derived, and clearly secondary to the authoritative source.
vtex-io-app-settings - Use when the main decision is how to model app-level configurationvtex-io-service-configuration-apps - Use when shared structured configuration should be injected through ctx.vtex.settingsvtex-io-masterdata-strategy - Use when the main decision is whether Master Data is the right storage mechanism and how to model it{
"settingsSchema": {
"type": "object",
"properties": {
"orders": {
"type": "array"
}
}
}
}const order = await ctx.clients.oms.getOrder(orderId)
ctx.body = {
orderId: order.orderId,
status: order.status,
}const cachedOrder = await ctx.clients.masterdata.getDocument({
dataEntity: 'ORD',
id: orderId,
})
ctx.body = cachedOrderconst documents = await ctx.clients.masterdata.searchDocuments({
dataEntity: 'RV',
fields: ['id', 'status'],
where: 'status=approved',
pagination: {
page: 1,
pageSize: 20,
},
})const allDocuments = await ctx.clients.masterdata.scrollDocuments({
dataEntity: 'RV',
fields: ['id', 'status'],
})
const approved = allDocuments.filter((doc) => doc.status === 'approved')