Embedding LOOPY Simulations in goern.name Blog Posts
Author: Roman “Romanov” Research-Rachmaninov Date: 2026-02-19 Bead: beads-hub-47n
Abstract
LOOPY (ncase.me/loopy) is Nicky Case’s open-source tool for creating interactive system dynamics simulations. Licensed CC0, built in pure JavaScript with no dependencies, it is ideal for embedding in static blog posts. This paper provides a complete guide for embedding LOOPY simulations in goern.name, covering iframe embedding, self-hosting, URL-parameter-driven pre-loaded models, responsive design, and a step-by-step Hugo integration guide.
Context — Why This Matters for #B4mad
goern’s blog (goern.name) discusses complex systems: agent architectures, open-source dynamics, decentralization trade-offs. Static text and diagrams fail to convey feedback loops and emergent behavior. LOOPY lets readers play with models — drag nodes, adjust relationships, run simulations — turning passive reading into active exploration. This is Nicky Case’s “explorable explanations” philosophy applied to #B4mad’s communication needs.
State of the Art
LOOPY Overview
- Repository: github.com/ncase/loopy
- License: CC0 (public domain) — no attribution required, fork freely
- Technology: Vanilla JavaScript, HTML5 Canvas, no build system, no dependencies
- File size: ~200KB total (JS + HTML + CSS)
- Browser support: All modern browsers, including mobile
Embedding Approaches in the Wild
- Direct iframe to ncase.me — simplest, used by many bloggers
- Self-hosted fork — full control, used by educators and researchers
- LOOPY v2 (loopy.surge.sh) — newer version with additional features, also embeddable
Analysis
Approach 1: Iframe Embedding (Quick Start)
The simplest method. LOOPY supports URL parameters that encode a full model state.
<iframe
src="https://ncase.me/loopy/v1.1/?embed=1&data=[encoded-model-data]"
width="800"
height="500"
frameborder="0"
style="border: none; max-width: 100%;"
loading="lazy"
allowfullscreen>
</iframe>
How to get the embed URL:
- Open ncase.me/loopy and create your model
- Click the share/export button — LOOPY encodes the entire model state as a URL parameter
- Append
&embed=1to hide the UI chrome and show only the simulation canvas
Pros: Zero setup, always up-to-date Cons: External dependency, potential latency, ncase.me could go down
Approach 2: Self-Hosting the LOOPY Engine
Given CC0 licensing, self-hosting is straightforward and recommended for production blogs.
Steps:
- Clone/fork
github.com/ncase/loopy - Copy the built files to your Hugo static directory:
static/ loopy/ css/ js/ index.html - Reference locally:
<iframe src="/loopy/index.html?embed=1&data=[model]" ...></iframe>
Advantages:
- No external dependency
- Faster loading (same-origin, CDN-cached)
- Can customize CSS/behavior (brand colors, dark mode)
- Works offline/on corporate networks that block external sites
- Full control over versioning
Approach 3: URL Parameters and Pre-loaded Models
LOOPY’s URL parameter system encodes the complete model as a JSON-like structure in the data parameter. The format includes:
- Nodes: position (x,y), label, initial value, color/hue
- Edges: source→target, relationship type (+/−), strength
- Labels: text annotations
Creating a model programmatically:
The data parameter is a URL-encoded array structure. While the format is not formally documented, inspecting the source reveals it follows this pattern:
data=[[[node1],[node2],...],[[edge1],[edge2],...],[[label1],...],screenX,screenY]
Each node: [id, x, y, initialValue, label, hue]
Each edge: [fromId, toId, arc, strength, label]
Workflow for blog authors:
- Design the model visually at ncase.me/loopy
- Export/share to get the data parameter
- Paste into the blog post’s iframe src
- The model loads pre-built when readers visit
Responsive Design Considerations
LOOPY renders to HTML5 Canvas, which doesn’t auto-resize. Solutions:
CSS-based responsive wrapper:
<div style="position: relative; width: 100%; padding-bottom: 62.5%; overflow: hidden;">
<iframe
src="/loopy/index.html?embed=1&data=[model]"
style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: none;"
loading="lazy"
allowfullscreen>
</iframe>
</div>
This maintains a 16:10 aspect ratio and scales to container width.
Mobile considerations:
- Touch interactions work natively on LOOPY’s canvas
- Minimum recommended width: 320px (LOOPY remains usable)
- Consider adding a “tap to interact” overlay on mobile to prevent scroll-jacking
Dark mode:
Self-hosted version can be CSS-customized. The canvas background and node colors are set in JS — fork and modify css/ and the color constants in the source.
Step-by-Step Hugo Integration Guide
goern.name likely runs Hugo (standard for static blogs in the Go ecosystem). Here’s the complete workflow:
1. Set Up Self-Hosted LOOPY
cd your-hugo-site/
mkdir -p static/loopy
# Download LOOPY release files
curl -L https://github.com/ncase/loopy/archive/refs/heads/master.zip -o /tmp/loopy.zip
unzip /tmp/loopy.zip -d /tmp/loopy-src
cp -r /tmp/loopy-src/loopy-master/* static/loopy/
2. Create a Hugo Shortcode
Create layouts/shortcodes/loopy.html:
{{ $data := .Get "data" }}
{{ $width := .Get "width" | default "100%" }}
{{ $height := .Get "height" | default "500px" }}
{{ $caption := .Get "caption" }}
<figure class="loopy-embed">
<div style="position: relative; width: {{ $width }}; max-width: 800px; margin: 1.5em auto;">
<iframe
src="/loopy/index.html?embed=1&data={{ $data }}"
style="width: 100%; height: {{ $height }}; border: 1px solid #ddd; border-radius: 4px;"
loading="lazy"
allowfullscreen>
</iframe>
{{ with $caption }}
<figcaption style="text-align: center; font-style: italic; margin-top: 0.5em; color: #666;">
{{ . }}
</figcaption>
{{ end }}
</div>
</figure>
3. Use in Blog Posts
In any markdown blog post:
Here's how agent access and security interact:
{{< loopy data="[encoded-model-data-here]" caption="More access increases both usefulness and risk" >}}
As you can see by running the simulation...
4. Creating Models for Posts
Workflow:
- Visit ncase.me/loopy (or your self-hosted
/loopy/) - Build the model visually — add nodes, draw relationships
- Click share → copy the URL
- Extract the
data=parameter value - Paste into the shortcode’s
dataattribute
5. Example: Agent Security Trade-off Model
A simple model demonstrating #B4mad concepts:
- Node 1: “Tool Access” (green)
- Node 2: “Usefulness” (blue)
- Node 3: “Security Risk” (red)
- Node 4: “User Trust” (yellow)
- Edges: Access→Usefulness (+), Access→Risk (+), Risk→Trust (−), Trust→Access (+)
This creates a visible feedback loop: more access → more useful but riskier → erodes trust → reduces access. Readers can experiment with the dynamics.
6. Jekyll Alternative
If goern.name uses Jekyll instead of Hugo:
Create _includes/loopy.html:
<div class="loopy-embed" style="max-width: 800px; margin: 1.5em auto;">
<iframe
src="/loopy/index.html?embed=1&data={{ include.data }}"
style="width: 100%; height: {{ include.height | default: '500px' }}; border: 1px solid #ddd; border-radius: 4px;"
loading="lazy"
allowfullscreen>
</iframe>
{% if include.caption %}
<p style="text-align: center; font-style: italic; color: #666;">{{ include.caption }}</p>
{% endif %}
</div>
Usage in posts:
{% raw %}{% include loopy.html data="[model-data]" caption="Feedback loop visualization" %}{% endraw %}
Recommendations
Self-host LOOPY — Copy the ~200KB engine into
static/loopy/. Zero dependency, full control, CC0 makes this frictionless.Create the Hugo shortcode — The
{{< loopy >}}shortcode reduces embedding to a one-liner per post. Takes 5 minutes to set up, saves time on every future post.Build a model library — Create reusable models for recurring #B4mad concepts (agent dynamics, governance feedback loops, open-source sustainability). Store the data strings in a reference file.
Use responsive wrappers — The CSS approach above ensures models work on mobile without additional JavaScript.
Consider LOOPY v2 — The newer version (loopy.surge.sh) adds features like adjustable simulation speed. Evaluate whether the additional capabilities justify the switch. The embedding approach is identical.
Add lazy loading — The
loading="lazy"attribute on iframes prevents LOOPY from loading until scrolled into view, keeping page performance crisp for posts with multiple simulations.Customize for brand — Fork LOOPY and adjust the color palette and canvas background to match goern.name’s theme. This is a minor CSS/JS edit.
References
- LOOPY source: github.com/ncase/loopy (CC0)
- Nicky Case’s explorable explanations: ncase.me
- LOOPY v2: loopy.surge.sh
- Hugo shortcodes documentation: gohugo.io/templates/shortcode-templates/
- Jekyll includes documentation: jekyllrb.com/docs/includes/
- HTML5 iframe responsive patterns: developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe