{"slug": "building-a-generative-jewelry-configurator-with-vanilla-js-svg-and-numerology", "title": "Building a Generative Jewelry Configurator with Vanilla JS, SVG, and Numerology", "summary": "GemStudio 360, a project by Lochness Paris, built a generative jewelry configurator using vanilla JavaScript, SVG, and numerology. The tool converts a user's name and birth date into eight symbolic gemstones, renders them as procedurally generated SVG beads, and allows fine-tuning before sending the design to a human artisan. The team deliberately avoided frameworks to optimize load time and maintain full control over state management and PWA behavior.", "body_md": "published: false\n\ndescription: How GemStudio 360™ turns a name and a birth date into a one-of-a-kind, hand-crafted bracelet — and why we built the rendering engine without a single framework.\n\ntags: javascript, svg, pwa, webdev\n\ncover_image:\n\ncanonical_url: [https://lochness-paris.com/configurateur-de-bracelet.html](https://lochness-paris.com/configurateur-de-bracelet.html)\n\nA few months ago we set out to build something that doesn't fit neatly into the usual \"product configurator\" template: a tool that turns your name and birth date into a personalized gemstone bracelet, lets you fine-tune every single bead by hand, and ends with a real artisan crafting the physical piece.\n\nTurn an identity (first name, last name, birth date) into 8 symbolic gemstones, let the user build a real bracelet around them bead by bead, and hand the final design off to a craftsperson.\n\nNo accounts, no backend database of users, no checkout — just a fast, installable web app that ends in a personalized request sent to a human artisan.\n\nWhy no framework?\n\nThis was a deliberate choice. The whole app — numerology engine, SVG bead renderer, drag-to-build canvas, smart suggestions, cart — is built in vanilla JavaScript, plain CSS, and a single HTML file.\n\nThree reasons drove that decision:\n\nLoad time matters more than developer convenience here. A big chunk of traffic comes from organic/mobile search for terms like \"bracelet chemin de vie.\" Every extra hundred kilobytes of framework runtime is a few more bounces.\n\nThe DOM tree is genuinely simple. Four tabs, one SVG canvas, a handful of lists. State management doesn't need a library when the state is \"an ordered array of beads plus some UI flags.\"\n\nPWA installability and offline behavior are easier to reason about when you fully control the bootstrapping sequence instead of going through a framework's hydration lifecycle.\n\nThat said — vanilla JS at this scale means you have to be disciplined about state, which brings us to the next point.\n\nState management without a framework\n\nThe entire bracelet is represented as an ordered array of bead objects. Every mutation (add, remove, reorder, change size) goes through a small set of functions that:\n\nupdate the array,\n\npush the previous state onto an undo stack,\n\nre-render only the parts of the SVG that changed.\n\nThat last point matters a lot for performance: with up to ~19 beads rendered as gradient-filled SVG circles, a naive full re-render on every drag event is noticeable on mid-range phones. Re-rendering only the affected bead (and recalculating positions trigonometrically around the guide circle) keeps things smooth.\n\n```\n// Simplified illustration of bead positioning on the guide circle\nfunction getBeadPosition(index, total, radius, center) {\n  const angle = (index / total) * 2 * Math.PI - Math.PI / 2;\n  return {\n    x: center.x + radius * Math.cos(angle),\n    y: center.y + radius * Math.sin(angle),\n  };\n}\n```\n\nUndo/redo is just two stacks of array snapshots — simple, but it's the kind of \"boring technology\" that makes a configurator feel trustworthy. Users mis-click constantly; cheap undo is a UX feature, not a nice-to-have.\n\nGenerating gemstones instead of photographing them\n\nThis is the part I find most interesting. With 70+ stone types in the catalog, maintaining a photo library (multiple angles, lighting consistency, file size, retina variants…) would have been a maintenance nightmare.\n\nInstead, every bead is a procedurally generated SVG. Each stone type has a \"preset\" describing its visual family (translucent crystal, opaque mineral, banded stone, metallic finish…), and each individual bead instance gets a random seed that introduces small variations — hue jitter, gradient stop shifts — so that no two beads of the same stone type look perfectly identical, the same way no two real gemstones do.\n\nA heavily simplified version of the idea:\n\n``` js\nfunction renderBead({ id, baseHue, seed }) {\n  const rng = seededRandom(seed);\n  const hue = baseHue + (rng() - 0.5) * 12; // small natural variation\n\n  return `\n    <radialGradient id=\"grad-${id}\" cx=\"40%\" cy=\"35%\" r=\"65%\">\n      <stop offset=\"0%\"  stop-color=\"hsla(${hue}, 45%, 75%, 1)\" />\n      <stop offset=\"60%\" stop-color=\"hsla(${hue}, 45%, 55%, 1)\" />\n      <stop offset=\"100%\" stop-color=\"hsla(${hue}, 45%, 35%, 1)\" />\n    </radialGradient>\n    <circle cx=\"50\" cy=\"50\" r=\"48\" fill=\"url(#grad-${id})\" />\n  `;\n}\n```\n\nThe production renderer is considerably more involved — it layers multiple gradients, clip paths, and noise patterns per mineral family to approximate veining (think lapis lazuli or labradorite) and translucency — but the core trick is the same: vector + seed beats a static image library when you need infinite, lightweight variation.\n\nThe numerology layer\n\nThe app's signature feature is the \"Life Path Bracelet\": you type in a first name and a birth date, and the engine computes 8 symbolic stones — Foundation, Summit, Life Path, Calling, Personality, Expression, Final Touch, and Wish — each tied to a different facet of numerology.\n\nI won't detail the letter-to-number mapping or reduction rules here since that's the proprietary core of the product, but structurally it's a pure function:\n\n```\nidentity (name + date) → numeric reduction → archetype (1–9) → stone(s)\n```\n\nKeeping it as a pure, side-effect-free transformation made it trivial to unit test and to keep completely decoupled from the rendering and cart logic. The numerology module has no idea an SVG even exists.\n\nSmart suggestions and the \"litho score\"\n\nBeyond manual bead-picking, there's a \"Smart\" tab with:\n\nHarmonious palettes — pre-grouped stones by color coherence,\n\nPredefined themes — ready-made compositions for intents like \"protection\" or \"calm,\"\n\nA coherence score that evaluates how energetically consistent a user's manual selection is.\n\nThese are all derived/precomputed layers sitting on top of the same stone catalog — no real-time AI inference, just well-structured data and some scoring heuristics. It's a good reminder that \"smart suggestions\" don't always need a model; sometimes a well-curated lookup table does the job at a fraction of the latency and cost.\n\nPWA bits that actually mattered\n\nA few small, unglamorous details ended up making a real difference on mobile:\n\n`touch-action: manipulation`\n\non all interactive elements to kill the old 300ms tap delay.\n\nLoading the webfont with `media=\"print\"`\n\nthen switching to `all`\n\non load, so it never blocks first paint.\n\nA Service Worker caching static assets for offline resilience and faster repeat visits.\n\nA `manifest.json`\n\nso the app can be installed straight from the browser, no app store round-trip.\n\nNone of this is novel, but it's the kind of checklist that's easy to skip under deadline pressure — and it's exactly the stuff that determines whether a configurator feels like an app or like a website pretending to be one.\n\nFrom pixels to a physical object\n\nThe configurator deliberately doesn't end in a checkout button. Once a composition is validated, the user lands on a recap + contact form, and the actual fulfillment is handled by a human artisan partner who crafts the bracelet by hand using the validated design as a spec sheet.\n\nThat constraint shaped a lot of UI decisions — for instance, the cart view always shows an estimated price range rather than a fixed price, since the final quote depends on material choices (precious metal findings, natural pearls, etc.) confirmed with the artisan.\n\nWhat's public, what isn't\n\nWe open-sourced the documentation and architecture of this project, along with a few deliberately simplified code examples, in a public GitHub repo. What you'll find there:\n\na full architecture breakdown (diagrams included),\n\na feature-by-feature functional spec,\n\nsimplified illustrative examples of the numerology pattern and the SVG bead rendering pattern (not the production algorithms),\n\na roadmap and contribution guidelines.\n\nWhat stays closed: the actual numerology letter/reduction tables, the full multi-preset rendering engine, the complete stone catalog, and the litho-score algorithm — those remain Loch Ness®'s IP.\n\nTry it\n\nThe live configurator is here: lochness-paris.com/configurateur-de-bracelet.html\n\nThe project is also archived and citable via Zenodo: zenodo.org/records/19836838\n\nIf you're into vanilla-JS architecture, generative SVG, or PWA details, I'd genuinely love feedback — open an issue on the repo or drop a comment below.", "url": "https://wpnews.pro/news/building-a-generative-jewelry-configurator-with-vanilla-js-svg-and-numerology", "canonical_source": "https://dev.to/spiritrackingarch/building-a-generative-jewelry-configurator-with-vanilla-js-svg-and-numerology-7n0", "published_at": "2026-06-22 01:41:38+00:00", "updated_at": "2026-06-22 02:09:49.271178+00:00", "lang": "en", "topics": ["generative-ai", "developer-tools", "ai-products"], "entities": ["GemStudio 360", "Lochness Paris"], "alternates": {"html": "https://wpnews.pro/news/building-a-generative-jewelry-configurator-with-vanilla-js-svg-and-numerology", "markdown": "https://wpnews.pro/news/building-a-generative-jewelry-configurator-with-vanilla-js-svg-and-numerology.md", "text": "https://wpnews.pro/news/building-a-generative-jewelry-configurator-with-vanilla-js-svg-and-numerology.txt", "jsonld": "https://wpnews.pro/news/building-a-generative-jewelry-configurator-with-vanilla-js-svg-and-numerology.jsonld"}}