Skip to main content

Product types explained

Every product in SKU.io has a type. The type is the single most important thing about a product's shape: it decides whether the product holds its own stock, whether it stands alone or groups other products, and how it behaves when it appears on a sales order. There are six types — standard, kit, bundle, matrix, blemished, and manufactured — and understanding the split between them makes the rest of the catalog (and the inventory, ordering, and reporting that build on it) fall into place.

Type is stored as a plain string on the product; there is no separate "service" or "non-inventory" type. Non-stock behavior is expressed either by choosing a type that doesn't carry inventory (bundle, matrix) or by setting independent boolean flags on a product. This page explains the model and its cross-system effects. For the tasks themselves — building bundles and kits, creating a blemished copy, or converting a product from one type to another — see the how-to guides linked throughout.

The two questions that define every type

Two questions separate the six types:

  1. Does it carry its own inventory? Some types have a real inventory ledger — FIFO layers and inventory movements of their own. Others never hold stock; they exist to group or reference products that do.
  2. Does it stand alone, group other products, or reference another product? A standard product is self-contained. A bundle and a matrix are containers. A blemished product is a copy that points back at an original.

Inventory-bearing types

Standard, kit, blemished, and manufactured each carry their own inventory. They can have FIFO layers, receive stock, be counted in a stock take, and appear with an On-Hand number. When you sell one, a sale inventory movement is recorded against it. These are the products that show up in inventory reports and valuation.

Non-inventory types

Bundle and matrix never hold stock of their own. A bundle is a virtual grouping — its stock and value live in the components it points to. A matrix is a parent container whose sellable units are its child variations. Because they have no ledger, they don't appear as stock lines in inventory valuation; their children (or components) do.

This split is enforced, not cosmetic. SKU.io blocks converting an inventory-bearing product into a non-inventory type once the product has a real inventory ledger — a FIFO layer or any inventory movement, including a stock-take-established balance. Allowing the change would orphan those layers and movements. See Convert & auto-detect product types for how conversion and its guards work.

The six types

TypeHolds own inventory?ShapeWhat it's
StandardYesStands aloneA single, self-contained sellable product. The default and most common type.
KitYesAssembled from componentsA product with its own stock that's built from component products. It sells as one line but tracks its own inventory, like a standard product.
BundleNoGroups componentsA virtual grouping of other products. Holds no stock — at sale it explodes into its component lines, and the sale amount is prorated across them.
MatrixNoParent with variationsA parent container whose sellable units are its child variations (for example, a shirt with Size and Color variants). The parent itself carries no price or stock.
BlemishedYesCopy of a standard productA replicated copy of an existing product held at a tracked condition (for example, open-box, damaged), with its own stock separate from the pristine original.
ManufacturedYesBuilt via BOMs / assembliesA product with manufacturing enabled, produced through bills of materials and assemblies. Carries its own stock.

Kit vs bundle — the key distinction

Kits and bundles look similar (both are "made of" other products) but behave oppositely at the inventory ledger, and this is the distinction people most often get wrong:

  • A kit has its own stock. You assemble it ahead of time (consuming component stock to produce kit stock), and it sells as a single line against its own On-Hand.
  • A bundle has no stock of its own. It stays "virtual" until a sale, at which point it expands into its component lines and the price is spread across them.

Because a bundle's revenue is split across components, SKU.io picks a proration basis automatically: cost when every component has a unit cost, price when every component has a price but not all costs, otherwise quantity (split by recipe quantities). See Kits vs bundles and Bundle pricing & revenue proration for the full model, and Build bundles & kits in the Workshop to assemble them.

Blemished products

A blemished product is created by replicating an existing standard product and tagging it with a condition. The copy takes the original's SKU with a -blemished-<condition> suffix and gets its own inventory ledger, so damaged or open-box stock is tracked and sold separately from pristine stock. The condition (and an optional reference) live on the blemished record. See Create a blemished product.

Service and non-inventory products (expressed via flags)

SKU.io has no dedicated "service" or "non-inventory" product type. Anything that shouldn't behave like a normal stocked good is expressed one of two ways: by using a non-inventory type (bundle or matrix), or by setting one of several independent boolean flags on the product. These flags aren't a single status — a product can have any combination of them.

FlagWhat it controls
Sellable (is_sellable)Whether the product can be sold. A non-sellable product (for example, a raw component or internal item) is excluded from selling flows.
Dropshippable (is_dropshippable)Whether the product can be fulfilled by dropship rather than from your own stock.
Decoration consumable (is_decoration_consumable)Marks a raw material of decoration — thread, ink. These are the only product kind that can't itself be decorated: a product is decorable when it's not a decoration consumable. Every other kind (finished goods, blanks, manufactured) can carry a decoration spec.
Show in register (show_in_register)Whether the product appears in the POS/register. New products default this from the auto-show new products in register product setting (on by default), and you can override it per product.

Because these are independent booleans rather than one field, a "service-like" item is modeled by combining them — for example, a non-stocked charge line might be a standard product left out of inventory flows, while a consumable like thread is a normal stocked product flagged as a decoration consumable so the system knows it can't be decorated.

For the exact field names, defaults, and validation, see the Product fields & validation reference.

Variants: Internal matrix vs channel variable products

"Does SKU.io support variants?" has two answers, because there are two different concepts that both get called "variants." Keeping them straight avoids a lot of confusion.

Internal matrix variants (SKU.io's own model)

Inside SKU.io, variants are modeled with the matrix type. A matrix parent is a grouping container; its variations are the real, sellable child products, each with its own SKU, price, and stock. The link is a parent_id on each child pointing at the parent — a product "is a variation" precisely when it has a parent. The parent itself carries no price or stock; it exists only to group its variations.

The parent's shared children attributes decide which attributes vary across the set (for example, Size and Color) — these are the axes of variation that every child shares. Editing which attributes vary, and the variation-level attribute values, is gated by the manage variants product permission (products.manage_variants), so not every user who can edit a product can restructure its variations.

Two cross-system effects to know:

  • Archiving cascades. When you archive a matrix parent, the archive flows down to all of its variations automatically; unarchiving the parent restores them the same way. You don't archive variations one at a time. See Archive, unarchive & delete a product.
  • Children inherit at creation. When variations are created from the parent, they inherit shared fields (brand, type, dimensions, weight) and the parent's shared attributes, then apply their own variation-specific values on top.

For how the parent–variation structure sits alongside categories and attributes, see How product taxonomy works.

Channel variable products (a different thing)

Sales channels have their own notion of variants — WooCommerce "variable" products, Shopify products with variants — where a parent listing holds several sellable variations on the channel side. These aren't the same as SKU.io's matrix. Channel variations are mapped to internal SKU products during integration sync; the channel-side parent is a grouping container that typically has no price or stock of its own, so treating it as a normal sellable product is a reconciliation mistake — each channel variation should map to the internal product that actually holds the stock.

This mapping lives in the integrations layer, not the product catalog. Setting up channel listings and variant mapping is covered in the Listings guide (coming soon), not here.

Where inventory numbers come from

Types decide whether a product carries stock; they don't change how stock numbers are calculated. For how On-Hand (which includes non-sellable stock), Available, and the various stock states work, see Stock states explained and View a product's stock; for FIFO cost layers see FIFO layers & COGS. This concept page stays focused on the type model itself.

Next steps

Last verified: