The Obspec gem: Figma's five-piece mark carved from banded violet obsidian, on a polished obsidian plinth in a dark violet studio
Every note in your vault, one search away from the canvas.

Obspec · Figma plugin

Obsidian to Figma and back

Obspec is a Figma plugin I designed and built in the days after Figma's first Config in India. Search your Obsidian vault from inside Figma, drop any note on the canvas as a Spec, and keep the note and the design in sync. Nothing leaves your machine.

Scope
Product & plugin UX
TypeScript plugin + local bridge
Brand, 3D & landing site
Figma Community launch
Role
Designer & builder, solo
Pair
Claude Code, on every commit
Timeline
Oct 15 – 18, 2026
Outcome
Live on Figma Community
Open source, MIT
28 commits in 60 hours
Kamaldesigner & builder, solo
The Obspec site: an Obsidian vault and a Figma canvas side by side in one Mac window, with the Obspec plugin open and teammates' cursors on the canvas

Contents

The Process.

Seven chapters, from one conversation at Config to a plugin anyone can install. Read it the way it happened, or jump straight to a part.

01 / 07 Where it began

Spark

Figma brought Config to India for the first time. I went to listen, found a gang of six, and left with a promise to keep.

Spark · Config India 2026

Figma's first Config in India, and a gang of six.

It was an invite-only room. I went as a design-first builder, mostly to listen. I walked in alone, and within the first hour I had found a group. Six of us stayed together the whole day.

The gang at Figma Config India 2026, smiling in front of the giant green Config letters, lanyards onConfig India 2026 · the gang
Spec stood out. Code layers right behind it
Riya uses Obsidian. So do I
Left ZenMode OS on the doodle board

We talked design all day

  1. 01Where AI fits in a designer's week
  2. 02Whether craft still matters
  3. 03What good means now

I learnt more from those conversations than I expected.

The announcements

  • Code layers
  • Specstood out
  • A whole set of betas

The promise

Twelve hours later it worked

Later that day, Riya mentioned she uses Obsidian. So do I. I told her I'd try to build a Figma plugin for it. Twelve hours after the event, I had a first version working.

Why it stuck

I'd moved from Evernote to Obsidian a few months back, and I probably talk about it too much.

My whole working memory lives in a vault: product specs, research, design decisions. My designs live in Figma. Spec was the first announcement that made those two feel like they belonged on the same canvas.

  1. First commitPlugin, local vault bridge and a preview harness
  2. Site liveMarketing page, README shots, MIT licence, Pages deploy
  3. v1.0Specs export and the status chip on the frame

Spark · What Spec changed

Specs speak markdown, and so does Obsidian.

A Figma Spec is markdown. Drop any .md file on the canvas and Figma turns it into a native Spec. Every note in an Obsidian vault is already a plain .md file. The bridge was sitting right there.

Payment Methods.mdObsidian · Product/Specs
---
tags: [spec, checkout, payments]
status: draft
---# Payment MethodsOrder of methods on the payment step,
decided by device and locale.## Rules- Apple Pay first on iOS/Safari, Google Pay
  first on Android/Chrome
- Cards always available; PayPal only in
  US/UK/DE
- Remember last used method per account
  (see [[Checkout Redesign]])## Copy- Title: "How would you like to pay?"
- Helper: "You won't be charged until you
  confirm."
FigmaSpecSpec

#spec#checkout#paymentsdraft

Payment Methods

Order of methods on the payment step, decided by device and locale.

Rules

  • Apple Pay first on iOS/Safari, Google Pay first on Android/Chrome
  • Cards always available; PayPal only in US/UK/DE
  • Remember last used method per account (see Checkout Redesign)

Copy

  • Title: "How would you like to pay?"
  • Helper: "You won't be charged until you confirm."
The real demo-vault note, line by line. Frontmatter becomes tags, and the wikilink becomes plain text, so nothing dangles.

The catch: Figma ships no Plugin API for Specs. A plugin can't create one. So Obspec had to meet Specs halfway, and that became the first of four walls.

02 / 07 Two apps, one designer

Problem

The decisions live in Obsidian. The designs live in Figma. The space between them is where specs go stale.

Problem · The gap

Decisions in one app, designs in another.

The why behind a button, the rules for a payment step, the copy everyone agreed on: it all gets written down in notes. The frames that carry it out live in Figma. Paste a note into a frame and it starts going stale the moment either side changes.

The problem space

Specs get copy-pasted between two apps that never talk to each other, so nobody knows which side is right.

The solution

Obspec puts the vault one search away from the canvas, and keeps every note linked to the frames it describes, both ways.

  1. Monday

    The spec is pasted into a frame. Both sides agree.

  2. Wednesday

    The note changes: PayPal is now US only. The frame never hears about it.

  3. Friday

    The build follows the frame. Nobody knows which side was right.

A familiar week, and the reason a link has to know when either side moves.

Problem · Constraints

Four walls Figma puts around a plugin.

Two were known on day one. The other two showed up the first time the plugin met real Figma. None of them could be argued with, only designed around.

  1. 01

    A plugin can't read your disk

    sandbox + iframe · no file system

    So a tiny bridge runs on your own machine, indexes the vault and answers the plugin over localhost.

  2. 02

    Figma rejects IP addresses

    allowedDomains: "http://127.0.0.1" ✕

    So the manifest allows exactly http://localhost:27123, and the bridge listens on both 127.0.0.1 and ::1.

  3. 03

    Specs have no Plugin API

    Plugin API · no Specs endpoint

    So Obspec exports Spec-ready .md and writes only the blocks Specs understand: headings, lists, quotes, code. No tables.

  4. 04

    FigJam has no frames

    editorType: ["figma"]

    So the first release is Figma only. Spec cards are auto-layout frames, and FigJam can't hold one yet.

Problem · Scope

Two ideas, and nothing else.

The brief I held myself to, on the plugin and on the site: two ideas only, no info dump. Every feature had to serve one of them, or it didn't ship.

01

Search the vault inside Figma

Every note, by title, path, tag or body, in milliseconds.
02

Two-way sync with Figma Specs

Link a layer to a note. Pull changes in, send design back.
03 / 07 How it works

System

A plugin that can't touch your disk, a vault that can't talk to Figma, and a tiny bridge on localhost in between.

System · Architecture

Three hops, all on your machine.

The plugin's UI runs in an iframe and its logic in Figma's sandbox. Neither can see your disk, so a zero-dependency Node bridge does: it indexes the vault, watches it, and answers on localhost. Edit a note in Obsidian and the bridge pushes an event before you've switched windows.

Figma

Sandboxcode.ts · links, spec cards, snapshots
Plugin UIui.ts · search, preview, sync

Obspec Bridge

vault.tsindexer + fs.watch
search.tsranked, with snippets
server.ts12 routes, live events over SSE

Obsidian vault

  • Product/Specs/Payment Methods.md
  • Product/Specs/Checkout Redesign.md
  • Design/System/Button.md
  • Research/Checkout Interviews Oct.md
  • + every other .md file

bridge · replaying the demo flow

    It binds to 127.0.0.1 and ::1 only, allows just the plugin's origin, figma.com and localhost, and writes to the vault only when you press Send to Obsidian.

    System · Two-way sync

    Every link knows who moved.

    A link lives on the Figma layer itself, as plugin data: the note's hash and the layer's design fingerprint at the last sync. Compare them with what's there now and you know which side changed. No database, no account, no server keeping score. Try it.

    ObsidianProduct/Specs/Payment Methods.md

    obspec:link plugin data on the frame

    path
    Product/Specs/Payment Methods.md
    kind
    linked
    noteHash
    now
    designHash
    now

    computeSyncState() → in-sync

    FigmaCheckout
    # Checkout / Payment step 390 × 844 In sync

    How would you like to pay?

    Apple PayCard number Continue to payment

    The same FNV-1a hash and the same computeSyncState() the plugin ships, running on this page. Edit both sides to see Both changed.

    System · Performance

    From 26.5 seconds to 45 milliseconds.

    The demo vault has eleven notes. Mine has over six thousand. The first build worked out backlinks by scanning the whole vault every time you opened a note. A basename index and an inbound-link index turned that into a lookup.

    Opening one note · 6,000-note vault

    Before
    26.5 s
    After
    45 ms

    589× faster, on the same 6,000-note vault

    < 1 sto index 6,000 notes
    ~30 msfor a common-word search, server side
    80 mssearch debounce, 30 results a page
    0 bytesleave your machine
    04 / 07 The plugin

    Design

    A 500 × 780 window with three tabs. Everything a designer needs from their notes, and nothing they'd have to learn.

    Design · First run

    Two steps, then it gets out of the way.

    A plugin that needs a helper on your machine lives or dies on its first minute. The first run waits for the bridge and moves on by itself when it comes up, then lists the vaults Obsidian already knows about. Click one, and you're searching.

    1Obspec first run, step 1: start the bridge, with a copyable one-line command; the screen moves on by itself when the bridge answers
    Start the bridgeA copyable command. The screen moves on by itself when the bridge answers.
    2Obspec first run, step 2: pick a vault from the ones Obsidian knows about, browse for a folder, or paste a path
    Pick a vaultRead from Obsidian's own registry. Or browse for a folder, or paste a path.
    Remembered in ~/.obspec, never asked twice
    • 0accounts or sign-ins
    • 1command, once
    • 2screens to your first search

    Design · The spec card

    A note, rebuilt as a real Figma frame.

    Press Insert, or drag a result onto the canvas, and the note becomes an auto-layout frame: headings, lists, quotes, code and images become real layers. Drop it inside a frame or section and it lands right there. The status chip sits on the frame itself.

    • Source lineVault folder, always visible
    • TitleThe note's H1
    • TagsFrom frontmatter and #hashtags
    • BodyHeadings, lists, quotes, code
    • FooterOpen in Obsidian, path, word count
    An Obspec spec card on the Figma canvas: OBSIDIAN · Product/Specs, an In sync chip, the title Payment Methods, three tags, the Rules and Copy sections, and a footer with Open in Obsidian, the path and 65 words
    • Live statusIn sync, Note changed, Design changed
    • Real layersText, not a picture of text
    • WikilinksBecome plain text, nothing dangles
    • Auto layoutGrows with the note on every Pull
    The card as the plugin builds it, on the preview harness canvas. Tap to zoom.

    Design · Flows

    Five things, end to end.

    Everything Obspec does fits in five flows, and every one of them runs in the preview harness with the real plugin UI and the real bridge. These stills are from it.

    Preview harness: the Payment Methods note inserted as a spec card on the mock Figma canvas, with Spec card inserted confirmed in the plugin
    Search the vault, open the note, Insert. The card lands on the canvas, already linked.
    Preview harness: a search result dragged out of the plugin and dropped on the canvas as a spec card
    Search “roadmap” and drag the result out of the plugin. The card appears where it was dropped.
    Preview harness: the linked note was edited on disk; the plugin shows Note changed and a Pull button
    A line is appended to the note on disk. Obspec shows Note changed live, and Pull brings it in.
    Preview harness: the Button / Primary component sent to Obsidian, creating a note with frontmatter and a Design table
    Select Button / Primary, Send to Obsidian. A note appears with size, fill, copy and a Figma link.
    Preview harness: the button label changed on the canvas, Obspec shows Design changed, and sending again updates the note's Design section
    Change the label on the canvas. Design changed appears, and sending again updates the note.

    Design · Views & themes

    Three layouts, two themes, one window you can stretch.

    The default window is 500 × 780, with a grip to resize it and the size remembered. Results come as Cards, a List or Compact rows, and the theme follows Figma's or overrides it.

    Obspec search results in the list layout, light theme
    List
    A note open in the Obspec plugin with rendered markdown, backlinks and Insert spec card
    Note preview
    Obspec in the dark theme
    Dark
    Obspec settings: the bridge connection card, vault, theme and support
    Settings
    05 / 07 The gem and the site

    Brand

    Figma's mark, carved from violet obsidian, and a landing page that went through ten rounds of feedback in one day.

    Brand · The mark

    Figma's mark, carved from violet obsidian.

    Obsidian is volcanic glass, and Figma is the canvas. So the logo is Figma's own five-piece mark, cut from banded violet obsidian. It renders live in three.js on the site, from the 50px header gem to the big one on its plinth. These stills come from the same code.

    38 × 57r 9.5
    01Five piecesFigma's mark on its 9.5-unit grid, one shape per piece.
    The five Figma pieces extruded in violet obsidian and pulled apart, showing chiselled bevels and faceted arcs
    02ExtrudedChiselled bevels, and few curve segments on purpose, so arcs read as facets.
    The assembled Obspec gem: the Figma mark in banded violet obsidian, clearcoated, lit from behind
    03ObsidianBanded violet texture, clearcoat, a warm backlight and a violet fill.
    1. v5An obsidian stone with the Figma mark on it
    2. v6Stone in 3D, the mark kept flat
    3. v7Black glass. No glitter, no halo, no wireframe
    4. v10The logo is the gem
    5. v11A polished plinth, after the jagged rock

    Brand · The site

    Ten rounds of feedback, one landing page.

    I was my own toughest client. The site went from v3 to v12 in a single day, each round a short brief, some of them a single line (quoted). Only two ideas were ever allowed on it. Everything else got cut.

    1. v3Cheap, garish and generic

      3D notebooks on a rail. Thrown out entirely.

      Rejected
    2. v4Two screens, scrubbed by scroll

      OffBit display type, Apple's system font, Obsidian and Figma side by side, scrubbed by scroll.

      Rebuilt
    3. v5Doesn't fit

      Cobalt and orange out. Obsidian glass in: near-black, paper and one Obsidian purple.

      Recoloured
    4. v6Stone 3D, mark flat

      One fixed stage, no footer. Six states and an outro where the window lifts away.

      Restaged
    5. v7Seven fixes in one brief

      A scroll button that names the next step, black glass, and teammates' cursors on the canvas.

      Seven fixes
    6. v8Wasn't catchy

      The purple banner became paper white. A laurel badge and a mock frame that draws itself.

      Rewritten
    7. v9Open source again

      A glass medallion, a banner that folds itself after 15 seconds, and a Contribute button.

      Opened up
    8. v10The logo becomes the gem

      Figma's five pieces carved from obsidian, in the header and in the outro.

      Kept
    9. v11It's Obsidian X Figma Spec, not the other way

      Repo and Pages live, the lockup reordered, a polished plinth.

      Shipped
    10. v12Breathing space

      Wider gutters, a capped window, and the award reduced to grey line-work.

      Live

    Brand · The scroll

    Six states, one scroll.

    The whole site is one fixed stage. Scroll scrubs six states, both ways, because everything derives from a single progress value: search, results, a note flying through the seam, the link, a Pull and a Send. Drag the scrubber to play it.

    Step 1: Search your vault inside Figma. The Obsidian vault and the Figma canvas in one Mac window Step 2: Type once, find everything. Results light up in the vault Step 3: Drop a note on the canvas. The note becomes a Spec card Step 4: Linked both ways. A thread ties the Spec to its note Step 5: Edit in Obsidian, pull in Figma Step 6: Change the design, send it back. Size, fill, label and a deep link travel into the note The outro: the Obspec gem on its plinth, with Get the plugin on Figma

    Shot from the live site's code at 2×, with the announcement banner folded away.

    06 / 07 From first commit to Community

    Ship

    28 commits in 60 hours, tested without opening Figma, through Figma's review, and down to one line in a terminal.

    Ship · The build log

    Every commit, from first line to Community.

    This is the step-by-step build: all 28 commits, on a real clock. The first one lands on Thursday night. The site ships Friday morning. Saturday afternoon is the first run in real Figma, and the listing goes live that evening. Press replay.

    0commits
    0 helapsed
    0lines added

      From the repo's git log. Every commit was co-written with Claude Code.

      Ship · Testing

      Tested without ever opening Figma.

      Testing a plugin by hand is slow. The preview harness runs the real plugin UI and the real bridge against a mock Figma document, with one-click emulations of every flow, and the same scenarios run headless in Chrome before anything ships.

      Obspec · local previewreal plugin UI · real bridge · mock Figma document
      The Obspec preview harness: a mock Figma canvas with checkout frames and a spec card, the real plugin window, and a rail of one-click use-case emulations with the Obsidian note shown live

      zsh · obspec

      $ npm test
      # tests 36
      # pass 36
      # fail 0
      # duration_ms 276.4
      • 36bridge, search, markdown and note tests, all green
      • 7end-to-end scenarios in headless Chrome
      • 27124the preview's own port, so a live plugin on 27123 is never touched

      Ship · Figma review

      Passing Figma's review, honestly.

      Figma's review reads the manifest and the data-security answers. Obspec's are short because there is almost nothing to declare: one localhost address, no account, no analytics, no AI.

      manifest.json

      {
        "name": "Obspec",
        "editorType": ["figma"],
        "documentAccess": "dynamic-page",
        "networkAccess": {
          "allowedDomains": ["http://localhost:27123"],
          "reasoning": "Obspec talks only to the Obspec
            Bridge running on your own machine
            (localhost:27123), which indexes your
            Obsidian vault. No data leaves your
            computer."
        }
      }
      Does the plugin collect, store or transmit user data?
      No. Notes are read over localhost from a folder on your own computer. No server, no sign-in, no trackers.
      Does it write to your files?
      Only on Send to Obsidian. Searching, previewing, inserting and linking are read-only.
      Third-party services or AI?
      None.

      First contact with real Figma · Sat 15:19 – 15:46

      1. Use the Figma-assigned plugin id
      2. A dev shim at the path Figma had registered
      3. Localhost-only network access, both loopbacks
      4. No symlinks, and listen for changes after pages load
      5. Spec card polish from the first real run

      Five fixes in 27 minutes, and the plugin ran in Figma for the first time.

      The Obspec Figma Community cover: Search your Obsidian vault inside Figma. Drop notes on the canvas as Specs. Keep both in sync, locally. A Payment Methods spec card reads In sync.
      The Community cover, rendered from an HTML listing page in the repo

      Ship · Install

      One line in a terminal, once.

      The first version asked you to start the bridge every time you opened Figma. My brief was blunt: “It's one time setup, not run the bridge every time.” Now one command installs it as a login service, and you never think about it again.

      Terminal

      $ npx github:Kamal007OLica/obspec
      Obspec Bridge v1.1.0 — one-time setup
        ✓ Installed to ~/.obspec/bridge/obspec-bridge.mjs
        ✓ Registered with launchd (starts when you log in)
        ✓ Running at http://localhost:27123 · no vault yet (pick one in Figma)
       
      Done. You can close this window — the bridge keeps running in the background and
      comes back on its own after a restart. Go back to Figma and pick your vault.
      • macOSa launchd agent in ~/Library/LaunchAgents
      • Linuxa systemd --user unit
      • Windowsa script in the Startup folder
      • Laterstatus · uninstall · run in the foreground
      07 / 07 What it taught me

      Reflection

      One conversation, one weekend, one plugin people can actually install.

      Reflection · Results

      Live on Figma Community

      45 hfirst commit to the Figma Community listing
      28commits, each one co-written with Claude Code
      589×faster note opens on a 6,000-note vault
      0bytes of your notes leave your machine

      From one conversation at Config to a plugin anyone can install.

      Reflection · Lessons

      What I'd tell the next person building one.

      Most of what made Obspec good was decided by things I couldn't change. The rest came from being a stubborn client to myself.

      1. 01

        Design around the walls

        No disk access, no IPs, no Specs API, no FigJam frames. Each wall became a decision: a local bridge, plain markdown, one localhost address.

      2. 02

        Let the site make promises

        The landing page said “insert them as Specs” and “status sits right on the frame” before the plugin did. Then a commit made both true.

      3. 03

        Test where Figma isn't

        The real UI and the real bridge against a mock document meant every flow could be checked in seconds, headless, before Figma ever saw it.

      4. 04

        Big vaults tell the truth

        Eleven demo notes hid a 26.5-second bug. Six thousand real ones found it. Always test with your own messy data.

      5. 05

        Setup is part of the product

        “Run the bridge every time” was a bug, not a step. One command, a login service, and the helper simply stays there.

      Reflection · What's next

      Where it goes from here.

      Straight from the README's own list of limits. Nothing here is promised by a date.

      Reflection

      Final thoughts before we leave.

      Leaving the gang at the end was the hard part.

      One day with six people, and it already felt like home. Obspec is what I brought back from it: a small, local tool for the way I actually work, built because Riya mentioned Obsidian and I said I'd try.

      Thank you, Figma, for coming to India. Thank you to the Figma community and every designer in that room.