← All implementations
CUSTOM GUITARS / COMMERCELive configurator

Sinstrum

An instrument as individual as its player.

sinstrum.com
Visit website ↗
The Sinstrum guitar builder showing an Oxblood S-style guitar in its 3D preview beside body options.
The actual guitar builder, with the 3D instrument preview and configuration controls.

Sinstrum brings a configurable guitar catalog into a purpose-built storefront. The work connects the expressive side of choosing an instrument with the less visible systems that make a build consistent.

The problem

A guitar is a set of connected choices. The storefront has to make those choices understandable while keeping the configuration and its price consistent from browsing to the cart.

The implementation

A Laravel and React application connects catalog options, server-calculated quotes, saved builds, and basket updates. NestedTerms supports the catalog, Priceable resolves component prices, and Stow manages cart and saved-build membership.

  • Custom guitar configuration and server-calculated quotes
  • Saved builds and an editable cart
  • Catalog administration and configurable checkout
01Choose components02Validate compatibility03Calculate quote04Save the build
02 / ENGINEERING DECISIONS

Where the details matter.

01

The server owns the quote

The builder offers immediate visual feedback, but the server checks component compatibility, availability and quantity-aware prices before producing cart lines.

02

Model a catalog, not a list of dropdowns

NestedTerms connects products to categories and child brands. Priceable supplies the scoped quantity lookup; the application decides what makes a valid instrument.

03

Reuse the basket, keep the instrument rules

Stow stores cart quantities and saved-build membership around the same guitar configuration. The application owns visitor boundaries, mutation locks, compatibility rules and server quotes.

03 / PACKAGES & CODE

Inside the implementation.

NestedTerms and Priceable are used in the catalog and quote path through embedded adaptations of their earlier APIs. Stow 2.1 handles database baskets for the cart and saved builds, with UUID-backed configurations. Application actions preserve ownership, quantity limits, repricing and checkout behavior.

APPLICATION EXCERPT

Component taxonomy

Priceable relationship initialization appears on first line; taxonomy attaches both category and child brand.

NestedTerms package ↗
database/seeders/CatalogSeeder.phpPHP
$product->prices()->firstOrCreate(['price_list_id' => null, 'min_quantity' => 1], ['unit_price' => $option['price'] / 100, 'currency' => 'USD']);
$product->attachTags($tag);
if (isset($option['brand'])) {
    $brand = Tag::firstOrCreate(['term_id' => $term->id, 'parent_id' => $tag->id, 'name' => $option['brand']], ['type' => 'string', 'value' => $option['brand'], 'is_active' => true]);
    $product->attachTags($brand);
}
Source excerpt · 107ac63 · lines 27–32. Surrounding setup is omitted.
APPLICATION EXCERPT

Quantity-aware component quote

Surrounding action validates configuration compatibility first and rejects missing prices.

Priceable package ↗
app/Actions/QuoteBuild.phpPHP
foreach ($lineSpecs as $spec) {
    $product = $products->get($spec['sku']);
    $this->ensure($product !== null && $product->is_active, 'configuration', 'A component is unavailable. Please update your build.');
    try {
        $unitPrice = $product->priceFor($quantity * $counts[$spec['sku']]);
    } catch (PriceNotFoundException) {
        $unitPrice = null;
    }
    $this->ensure($unitPrice !== null && $unitPrice >= 0, 'configuration', 'A component needs a current price before checkout.');
    $lines[] = ['sku' => $spec['sku'], 'name' => $product->name.$spec['suffix'], 'price' => (int) round($unitPrice * 100), 'quantity' => 1, 'category' => $spec['category']];
Source excerpt · 107ac63 · lines 67–76. Surrounding setup is omitted.
APPLICATION EXCERPT

Save a build in a named basket

The application validates the configuration and locks the visitor’s saved-build basket. Stow owns the item membership; the guitar snapshot, ownership and limit remain application rules.

Stow package ↗
app/Actions/ManageSavedBuilds.phpPHP
public function add(Request $request, array $configuration, ?string $name): GuitarBuild
{
    $quote = $this->quote->handle($configuration);

    return $this->baskets->mutate($request, 'saved-builds', function (BuildBasket $basket) use ($configuration, $name, $quote): GuitarBuild {
        $this->initialize($basket);
        abort_if($basket->items()->count() >= 50, 422, 'You can save up to 50 builds. Remove one before saving another.');
        $build = GuitarBuild::create(['owner_key' => $basket->owner_key, 'name' => $name ?? $quote['name'], 'configuration' => $configuration]);
        $basket->add($build);

        return $build;
    });
}
Actual application source · Stow 2.1. The shared basket mutation helper resolves the owner and acquires a database row lock.
APPLICATION EXCERPT

Shared attribution outside the application root

The host application keeps its own footer and copyright. A shared Blade component follows the application root, so client rendering does not duplicate it.

SiteCredit package ↗
resources/views/app.blade.phpBlade
<x-site-credit />
Actual component call; the package stylesheet is bundled through Vite.
04 / VERIFICATION & CURRENT SCOPE

What holds it together.

  • Compatibility and quote rules have explicit validation paths.
  • The case study shows a static capture of the real 3D builder.
  • Checkout availability is governed by the live application; no transaction volume is claimed.
  • Cart and saved-build tests cover visitor separation, existing-state migration, quantity bounds and repeated checkout clearing.
CURRENT RELEASE

Launch-stage storefront. Catalog and checkout availability are controlled by the live application.

KEEP EXPLORING

Growing, explained.

Designed, Developed and Hosted by Better Web Design and Development Services, LLC