<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jonas Sleiman</title>
    <description>The latest articles on DEV Community by Jonas Sleiman (@yojoxsn).</description>
    <link>https://dev.to/yojoxsn</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4241524%2F86e6ef64-8f3e-41ab-aae3-4c6875b65b74.jpg</url>
      <title>DEV Community: Jonas Sleiman</title>
      <link>https://dev.to/yojoxsn</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yojoxsn"/>
    <language>en</language>
    <item>
      <title>I turned my Obsidian vault into a 3D hologram I control with my hands</title>
      <dc:creator>Jonas Sleiman</dc:creator>
      <pubDate>Thu, 12 Nov 2026 17:21:55 +0000</pubDate>
      <link>https://dev.to/yojoxsn/i-turned-my-obsidian-vault-into-a-3d-hologram-i-control-with-my-hands-5553</link>
      <guid>https://dev.to/yojoxsn/i-turned-my-obsidian-vault-into-a-3d-hologram-i-control-with-my-hands-5553</guid>
      <description>&lt;p&gt;My Obsidian vault has around 2,000 notes. Obsidian's built-in graph view is nice, but I wanted something I could &lt;em&gt;grab&lt;/em&gt;: a 3D "second brain" I could rotate with my hand, like the holograms in Iron Man.&lt;/p&gt;

&lt;p&gt;So I built it. It is free, it runs entirely in your browser, and you can try it without installing anything:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Live demo:&lt;/strong&gt; &lt;a href="https://yojoxsn.github.io/vault-3d/" rel="noopener noreferrer"&gt;https://yojoxsn.github.io/vault-3d/&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Source (MIT):&lt;/strong&gt; &lt;a href="https://github.com/YojoxSn/vault-3d" rel="noopener noreferrer"&gt;https://github.com/YojoxSn/vault-3d&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnn495dpefyj67s7vbdpt.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnn495dpefyj67s7vbdpt.gif" alt="The orb turns, zooms in, a note lights up with its neighbours and its panel opens" width="600" height="338"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Captured from the live demo with mouse and keyboard.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I did not write the code by hand. I described what I wanted to &lt;a href="https://claude.com/claude-code" rel="noopener noreferrer"&gt;Claude Code&lt;/a&gt; in a long, structured prompt, then iterated. This post covers what the tool does, how it works, and the bugs that were worth the trouble.&lt;/p&gt;
&lt;h2&gt;
  
  
  What it does
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Orb mode.&lt;/strong&gt; Every note is a glowing sphere on a glass globe. Height is time (newest notes at the north pole), each root folder gets its own wedge, and well-connected notes sink toward a glowing crystal at the center. Notes that are linked but do not exist yet show up as wireframe "ghosts".&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Insights.&lt;/strong&gt; A panel that computes four lists from your graph: your &lt;em&gt;backbone&lt;/em&gt; (most connected notes), notes to &lt;strong&gt;write next&lt;/strong&gt; (ghost notes linked most often), &lt;strong&gt;orphans&lt;/strong&gt; to connect, and well-connected notes you have not edited in a long time. This turned out to be the most useful part.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hand control&lt;/strong&gt; (experimental). Open hand rotates, pinch clicks, two pinched hands zoom, a fist freezes the rotation, a swipe goes to the previous or next linked note. The video never leaves the browser tab.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Share card.&lt;/strong&gt; One button saves a picture of your own vault with its numbers. It contains only counts, never note titles, so it is safe to post.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Private by design.&lt;/strong&gt; Drop your vault folder on the page: it is read inside your browser, read-only, and nothing is uploaded.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F93u839u3z6engv7jlcav.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F93u839u3z6engv7jlcav.png" alt="A note with its links, neighbours lit up" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  The prompt
&lt;/h2&gt;

&lt;p&gt;The whole project started from a prompt written like a spec: context, numbered steps, concrete deliverables, and a few hard constraints. The shape was:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create an interactive 3D visualization of ALL my Obsidian vault with Three.js,
controllable with my hands through the webcam, like Tony Stark's hologram.

Step 1 - Import the vault: parse [[wikilinks]], aliases, markdown links, tags,
resolve links like Obsidian does; links to missing notes become "ghost" nodes.
The vault stays READ-ONLY.
Step 2 - 3D scene: sphere per note (size = connections, color = folder),
glowing links with particles, d3-force-3d layout. It must stay smooth with 3000+ notes.
Step 3 - Hand control with MediaPipe: open hand = rotate, pinch = click, ...
Everything must also work with mouse and keyboard.
...
At the end, give me the exact commands to install and run it.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three habits made the biggest difference: &lt;strong&gt;name the constraints&lt;/strong&gt; ("read-only", "3000+ notes", "works without a camera"), &lt;strong&gt;ask for tests&lt;/strong&gt;, and &lt;strong&gt;ask the assistant to say what it could not verify&lt;/strong&gt;. The full original prompts (in French) are in the repo: &lt;a href="https://github.com/YojoxSn/vault-3d/blob/main/PROMPT.md" rel="noopener noreferrer"&gt;PROMPT.md&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Parser.&lt;/strong&gt; A pure function turns markdown files into a graph. It handles &lt;code&gt;[[Note]]&lt;/code&gt;, &lt;code&gt;[[Note|alias]]&lt;/code&gt;, &lt;code&gt;[[Note#heading]]&lt;/code&gt;, embeds, &lt;code&gt;[text](Note.md)&lt;/code&gt;, inline and frontmatter tags, and resolves names the way Obsidian does (case-insensitive, closest folder wins). Because it is pure, the exact same code runs in the browser (drop a folder) and in a Node script (&lt;code&gt;VAULT_PATH&lt;/code&gt;). On a synthetic vault of 2,000 notes and 16,000 links it takes about 0.2 s.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rendering.&lt;/strong&gt; Spheres are one &lt;code&gt;InstancedMesh&lt;/code&gt; with a custom shader (fresnel rim, pulse, fog). All links are a single &lt;code&gt;LineSegments&lt;/code&gt;. The particles that flow along the links are animated &lt;em&gt;in the vertex shader&lt;/em&gt;, so there is no per-frame CPU work. Bloom plus a small post-processing pass (scanlines, chromatic aberration, grain) gives the hologram look.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Layout.&lt;/strong&gt; &lt;code&gt;d3-force-3d&lt;/code&gt; runs in a Web Worker so the UI never freezes; for 2,000 notes it needs about 5 s while the nodes stream in. The orb layout is a pure function instead of a simulation: latitude comes from the &lt;em&gt;rank&lt;/em&gt; of the modification date, longitude from the folder wedge, and the radius shrinks with the number of connections.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hands.&lt;/strong&gt; MediaPipe's HandLandmarker gives 21 points per hand. They go through a One Euro filter, then a pure gesture recognizer (open, fist, point, pinch with hysteresis), then a small state machine that handles debouncing, "quick pinch = click, held pinch = grab", the two-hand zoom, swipes and the fist-hold. Keeping the recognizer free of any DOM or MediaPipe code meant I could unit-test it with &lt;em&gt;simulated&lt;/em&gt; hands, no camera needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bugs that were worth it
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A click became a drag.&lt;/strong&gt; When you release a pinch, the thumb moves away and the midpoint between thumb and index drifts. The cursor moved, the "click" was rejected as a drag, and it would have landed in the wrong place anyway. The fix: track the &lt;strong&gt;index fingertip&lt;/strong&gt;, which barely moves, and remember where the cursor was when the pinch &lt;em&gt;started&lt;/em&gt;. A unit test caught it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Left/right hand labels are a trap.&lt;/strong&gt; Handedness labels depend on whether the video is mirrored. For the "both palms toward the camera" gesture I stopped trusting them and infer left vs right from the hand's position in the image instead.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A YAML regex swallowed a newline.&lt;/strong&gt; Tags written as a block list (&lt;code&gt;tags:&lt;/code&gt; then &lt;code&gt;- a&lt;/code&gt;) were read as the tag &lt;code&gt;-&lt;/code&gt;. Found by a test, fixed in one line.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One unreadable file broke the whole import.&lt;/strong&gt; An undownloaded iCloud placeholder throws when read. Now a single bad file is skipped and reported.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;"It stutters on my machine."&lt;/strong&gt; My first version looked great and ran badly on some graphics cards. The cost was mostly the full-resolution bloom and the glass-blur CSS over the animated canvas. There are now three quality levels, and &lt;strong&gt;Auto&lt;/strong&gt; lowers the quality by itself when the frame rate stays under 24 fps. On the software renderer I used for testing, the levels went from about 1.6 fps (high) to 7 (medium) to 18 (low), so the levels genuinely matter.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What I could not verify
&lt;/h2&gt;

&lt;p&gt;I want to be straight about the limits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The gesture thresholds are tested with simulated hands and in a real browser pipeline, but &lt;strong&gt;webcams, lighting and hands vary a lot&lt;/strong&gt;. Real-world tuning is not done, and I would love reports.&lt;/li&gt;
&lt;li&gt;I measured parsing and layout on 2,000 notes, but &lt;strong&gt;not the frame rate on a real GPU&lt;/strong&gt; at that size.&lt;/li&gt;
&lt;li&gt;The hand-control clip is the part I have not recorded yet, so the GIF above uses the mouse.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Try it, break it
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Open &lt;a href="https://yojoxsn.github.io/vault-3d/" rel="noopener noreferrer"&gt;https://yojoxsn.github.io/vault-3d/&lt;/a&gt; and press &lt;strong&gt;H&lt;/strong&gt; for hands mode (good light, 40-80 cm from the camera).&lt;/li&gt;
&lt;li&gt;Drop your own vault folder on the page and look at the &lt;strong&gt;Write next&lt;/strong&gt; list.&lt;/li&gt;
&lt;li&gt;Press &lt;strong&gt;P&lt;/strong&gt; to save a share card of your vault.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If it helps you, a ⭐ on &lt;a href="https://github.com/YojoxSn/vault-3d" rel="noopener noreferrer"&gt;the repo&lt;/a&gt; is the best way to help others find it. If something breaks, open an issue with your browser and webcam. And if you build your own version from the prompt, I would like to see what you get.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>showdev</category>
      <category>webdev</category>
      <category>threejs</category>
    </item>
  </channel>
</rss>
