Composition
A BOM is composed of components. Components come in three kinds — four if you count nesting via an assembly BOM. Each kind has slightly different mechanics at executionBOM executionEverything Assemblified does when a Shopify order containing a bill-bound variant is created, edited, cancelled or refunded: draw down pre-assembled stock, deduct or restore components, push the changes to Shopify, and cascade dynamic adjustment. It runs in the background, writing one execution log row. Read more → time. This page explains each one.
You edit all of this on the bill’s Materials tab.
In the materials table, the product name appears above its variant name in one column. Long names are shortened to fit. Hover over the name or focus it with the keyboard to see the complete product and variant together in one tooltip. Click or tap the name, or press Enter or Space, to open the complete name in a detail panel. Press Escape or tap outside to close it. Single-variant products do not show Shopify’s “Default Title” placeholder. The same layout is used on assembly bills.
On this page
Section titled “On this page”- Shopify-linked materials
- Virtual materials
- Assembly BOMs (subassemblies)
- The “BOM as raw” pattern
- A recipe cannot contain its own product
- Quantity and waste percentage
- Per-component locations
- Adding components to an existing bill
- Checking stock on the Materials tab
Shopify-linked materials
Section titled “Shopify-linked materials”The default. A real Shopify variant — wax, wick, jar, label, whatever — that you also stock in Shopify and want to deduct as it’s consumed.
When the BOM fires, Assemblified writes an inventory adjustment to Shopify via the Admin API. The component’s stock drops; the BOM’s finished-good stock is what was sold.
Use it for:
- Components you also sell standalone.
- Inventory you want visible in Shopify and on your storefront.
- Multi-location inventory you manage in Shopify.
Virtual materials
Section titled “Virtual materials”A virtual materialVirtual materialA material tracked entirely inside Assemblified — not a Shopify variant. Useful for shop-floor consumables (glue, packaging, labour units) where you need quantity tracking but don't want a Shopify product on your storefront. Read more → is internal to Assemblified — no Shopify variant. Inventory is tracked entirely in Assemblified. There’s no Shopify-side decrement.
Use it for:
- Consumables you don’t want in your Shopify catalog (tape, glue, screws, packaging).
- Materials you source from a non-Shopify supplier.
- Components tracked in tiny per-assembly quantities (one screw per unit) where setting up a Shopify product is overkill.
You create virtual materials from the Materials page — see Materials → Virtual materials. Once created, they show up in the component picker on the BOM detail page just like Shopify-linked materials.
You can also create one without leaving the bill: on the Materials tab, open Add materials and choose New virtual material. The same form opens, and on save the new material is added to the bill with a quantity of 1, ready for you to adjust.
Adding components to an existing bill
Section titled “Adding components to an existing bill”Everything above is added from one control: Add materials, in the heading of the Materials tab’s Components card. It offers four sources:
| Source | What it adds |
|---|---|
| Shopify materials | Opens Shopify’s product picker. Every variant you tick becomes a material row. |
| Virtual materials | Picks from the virtual materials you already have. |
| New virtual material | Creates a new one and drops it straight into this bill at quantity 1. |
| Import from CSV/XLSX | Reads a spreadsheet of components into this one bill. Different from the importer on the Finished goods page, which creates whole bills — see Import BOMs from a spreadsheet. |
For Import from CSV/XLSX, choose a CSV, XLS or XLSX file, or drag it into the dialog. Only the first selected file and the first spreadsheet sheet are read. Download template gives you the expected columns. Materials must already exist as Shopify or virtual materials.
Review New, Update, Not found and Invalid rows, edit Quantity or Waste %, or remove rows before importing. The classification buttons filter the preview; Import includes eligible rows across all filters. Wide previews scroll horizontally inside the table. Upload a different sheet resets the preview. Progress stays visible during import, and errors remain in the dialog for you to review and retry. Cancel is disabled while importing; closing the dialog does not undo rows already imported.
Quantity must be greater than zero and Waste % must be between 0 and 100, including zero. These rules also apply when you edit the preview. Invalid rows are excluded from Import until you correct them. For an Update row, leave Quantity or Waste % blank to keep its current value. Closing the dialog or choosing another file discards the pending preview, even if the earlier file is still being read.
Assembly BOMs have their own card below, with its own add control; additional cost rates have a third. Changes you make on this tab are held in the page’s form — the Save/Discard bar at the bottom of the screen is what writes them.
Assembly BOMs (subassemblies)
Section titled “Assembly BOMs (subassemblies)”An assembly BOMSubassemblyA reusable assembly block that composes into bigger bills: define it once, include it in any bill of materials, and Assemblified expands it into its own components at execution time. Its definition is an assembly BOM. Read more → is a reusable set of components — itself made of materials and (optionally) other assembly BOMs. Define once, drop into any BOM.
The navigation entry and the entity picker say Assembly BOMs for reusable definitions. A subassembly is the component defined by one of those BOMs; the card on a bill’s Materials tab and the create dialog’s source switch use that component label.
When the BOM fires, the subassembly is expanded recursively into its components. A subassembly has no Shopify variant of its own, but it can hold pre-assembled stock.
Use it for:
- Components shared across many BOMs (e.g., a “wick assembly” used in every candle).
- Reducing duplication when 20 BOMs share the same 10 underlying materials.
- Modeling a step in your assembly process you also build ahead of time.
Assembly BOMs can carry their own pre-assembled stockPre-assembled stockStock of finished goods and subassemblies already built and on the shelf, counted per location. For Shopify-linked finished goods, these units are part of the applicable on-hand balance, not extra stock to add to it. A work order draws subassemblies from the shelf first, building fresh only if it runs short; an order consumes a finished good's shelf before its components. Read more → . When a parent BOM expands one during execution, that shelf is consumed first — only the remainder pulls the assembly BOM’s own components.
See Subassemblies → Nesting & execution for the recursive expansion details.
The “BOM as raw” pattern
Section titled “The “BOM as raw” pattern”A BOM’s finished-good variant can itself be referenced as a material in another BOM. This is the “BOM-as-raw” pattern.
Example: you sell a “Wax Block” as its own product (BOM A). Then you also sell a “Candle Kit” (BOM B) that contains one Wax Block plus other components. The Wax Block’s variant appears as a material in Candle Kit’s component list.
When Candle Kit’s BOM fires:
- Assemblified looks up the Wax Block component.
- Recognizes that it is itself a finished good with a bill of materials.
- Treats Wax Block’s pre-assembled stock as the source — drawing from the shelf first.
- If Wax Block’s shelf is short, Assemblified does NOT recursively descend into Wax Block’s BOM. The expectation is that the Wax Block was either pre-built or its inventory is otherwise managed.
A recipe cannot contain its own product
Section titled “A recipe cannot contain its own product”A bill may use other finished goods as components, but never the product it makes. Every build would otherwise consume one unit of its own product, at that product’s cost. So Assemblified refuses a save that would put the bill’s own product into its recipe — directly, anywhere inside one of its assembly bills, or through a component added by a location rule. The message names the component to remove and, when it sits deeper, the assembly bill that holds it.
The check applies however the recipe is written: editing the bill, an upload or import, a duplicate, attaching the bill to a different product, a bulk edit, and a version restore. It works from the other side too: an assembly bill that a bill uses cannot gain that bill’s product as a component.
A recipe saved before this check existed is not changed on its own. The check looks at the components you save, so the next time you save that bill, remove the offending component.
Quantity and waste percentage
Section titled “Quantity and waste percentage”Every component reference carries:
- Quantity per BOM unit. How many of this component are consumed when the BOM produces one finished good. Decimals are supported (e.g., 0.5 meters of cable per unit).
- Waste percentage. A margin applied during execution:
effective_consumed = quantity × (1 + wastePercentage / 100). Useful for materials with predictable loss (cuts, trimmings, evaporation). 5% is a typical default; some processes have 10–20%.
Both are edited directly in the row on the Materials tab.
For assembly BOMs, only the quantity field exists. They don’t carry waste% at the parent level — waste lives on the assembly BOM’s own material references.
From each component’s quantity and its material’s weight, Assemblified derives a calculated weight for the BOM — the unit-converted sum of everything it consumes. The weight roll-up excludes waste percentage (scrap isn’t shipped), which is a deliberate divergence from the cost roll-up. It’s surfaced in BOM and assembly BOM exports today.
To include human labour in the rollup as a per-unit line, see Track building cost — the standard pattern uses a virtual material with unit cost = hourly rate.
Per-component locations
Section titled “Per-component locations”By default, components are consumed from the default Shopify location (configured in your store settings). The Materials tab’s Location override column is where you change that per component:
- Pick a location on a Shopify-linked material’s row to always pull that component from there, regardless of where the order ships from.
- Leave it on the default and the component is consumed from your default location — or from the location the order is fulfilled from, once multi-location sensitive adjustments are on. The ⓘ in the column header tells you which of the two fallbacks is in force for your store.
This is useful for multi-warehouse setups where components are stocked separately. See Materials → Inventory tracking for the full picture.
Checking stock on the Materials tab
Section titled “Checking stock on the Materials tab”The Components and Subassemblies tables on the Materials tab help you see at a glance whether you have what one unit of this bill needs.
- Search. Each table has its own search bar above it. Type part of a name, a SKU or (for materials) a variant title and the table narrows as you type. Searching only changes what you see: rows you ticked stay ticked, and the totals still count every line.
- The column header stays put. On a long bill, the column names stay at the top of the screen as you scroll.
- Location. When your store has more than one location, the search bar also holds a location button. It starts on All locations; pick one and both tables show that location’s numbers. Switching is instant — the stock is read once when the page opens. The choice is not saved: reopening the page starts on All locations again.
- Stock per location. Click a material’s Available number (or a subassembly’s Pre-assembled number) to open a small card with its stock at every location. The location the number is shown for is marked.
- Location overrides win. A material with a location override is always shown for that location, whatever location is picked in the search bar — it is the location the material is actually taken from — and its card says so.
What the highlight means
Section titled “What the highlight means”A number shown as a warning badge (with a warning icon) means there is not enough of this material for one unit of the bill at that location right now. “Enough” includes waste: a line needing 2 with 10% waste needs 2.2. A screen reader hears “Not enough for one unit” after the number, and the card behind it states what one unit needs.
- With a location chosen (or for a line with a location override), the check is for that one location.
- On All locations, a line is highlighted when it falls short at any location — not against your total stock across all locations — and its card shows the same badge on each location that is short.
- A subassembly is highlighted only when its pre-assembled stock is short and its own components there cannot make up the difference, so one you can still build is not flagged.
- A non-essential material that is below what one unit needs is shown as a blue info badge instead and is not treated as short: it is worth knowing, but it never limits how many you can build. Its card says so too.
Nothing is highlighted while stock is still loading or if it could not be read.
Where to next
Section titled “Where to next”- Settings reference — once your composition is set, configure how the BOM behaves.
- Execution model — see how composition translates to inventory adjustments at order time.