Jeg trækker mine boards ud af Miro og ind i Obsidian
Export-knappen i Miro giver dig en PNG eller en PDF — et foto af dataene, ikke dataene selv. Hvis dine boards er load-bearing maps of thinking bygget op gennem år, hører de hjemme i Obsidian: editable, searchable, i et lokalt vault. Sådan trak jeg boards ud af Miro via REST API og konverterede til Excalidraw / Obsidian Canvas — med positioner, farver, fonts, curved connectors, mindmap nodes — og lektien rækker længere end Miro: enhver SaaS skal mødes med en exit plan FØR du åbner den første gang.
Ethvert værktøj, der bor i browseren, holder dig som gidsel for sit UI. Især når du har lagt tid, kort og boards i det — og pludselig opdager, at din map of thinking ligger på en andens server, i et format du ikke kan åbne uden deres side.
Jeg har et par Miro-boards, der for længst er blevet load-bearing — refleksioner, planer, mentale kort bygget op gennem år. Export-knappen giver dig en PNG eller en PDF. Det er ikke data, det er et foto af dataene.
Hvorfor hente dem ud
Vendor lock-in er ikke et teoretisk problem. Det er meget konkret: for at hente dine egne data ned via API'et skal du upgrade til Expert tier. Du betaler altså for tilladelse til at hente det tilbage, der allerede er dit.
Jeg har længe levet efter Obsidian-first-princippet: alt vigtigt ligger i et lokalt vault, som plain files, jeg kan git-e, grep-e og læse om ti år. Et værktøj, der ikke eksporterer til det format, er et værktøj, du skal trække dig ud af, før afhængigheden bliver umulig at bryde.
Hvorfor Export ikke redder dig
Export-knappen i Miro giver dig en PNG eller en PDF. Det er raster — strukturen er væk. Du kan ikke ændre teksten i en box. Du kan ikke flytte en shape. Du kan ikke grep-e en etiket. Det er dødsannoncen for boardet, ikke boardet selv.
Obsidian har to alternativer, der bor inde i vaultet: Excalidraw-pluginet og det indbyggede Canvas. Begge er JSON. Begge er editable. Begge er searchable. Begge ligger i dit vault ved siden af noterne, og du kan grep-e teksten direkte fra Obsidian.
Sådan trækker du dem ud, når der ikke er nogen 'Export to Obsidian'-knap
Når UI-Export ikke giver dig det, du har brug for, kravler du ind i API'et. Miro har en REST API: den returnerer en JSON-beskrivelse af hver shape på et board. Excalidraw og Obsidian Canvas er begge open-format JSON. Mellem dem ligger en mapping.
Jeg skrev to Python-scripts. miro_to_excalidraw.py og miro_to_canvas.py. Standard library only — nul deps. Du kører dem med en token og et board ID, får en fil og smider den i vaultet.
Hvad der overlevede konverteringen
Opgaven var ikke bare at flytte shapes — det var at bevare det visuelle, så boardet læses præcis som i Miro.
- Positioner og størrelser — koordinaterne for hver shape 1:1
- Farver med fill opacity (40 % gult forbliver 40 % gult)
- Borders — farve, bredde, stil (solid / dashed)
- Fonts og alignment — monospace forbliver monospace, center forbliver center
- Connectors — pilene sidder i præcis de punkter, hvor Miro fæstede dem
- Curved connectors — bow-buer i stedet for lige linjer
- Images indlejret i filen (ikke eksterne URL'er)
- Mindmap nodes — teksten hentet ud via experimental Mindmap API
- Z-ordering — overlappet bliver ikke filtret
Hvor det blev ubehageligt
Miros API har et par huller, jeg måtte arbejde mig udenom via reverse engineering.
- Curved connectors — Miro eksponerer ikke control points i API'et. Så i stedet for den eksakte originalkurve syntetiserer jeg en bow — en bue med fast radius mellem de to endpoints. Visuelt tæt på, mathematically ikke identisk.
- Z-index — Miros API returnerer slet ikke et z-felt. Hvilken shape skal ligge øverst, hvilken nederst? Heuristik: større areal = længere tilbage. Det virker, fordi i rigtige boards sidder de store containere som regel under de mindre elementer.
- Mindmap — teksten i mindmap nodes er ikke tilgængelig via den almindelige items API. Du skal bruge et separat kald til experimental Mindmap endpoint. Filled nodes bliver til boxes, unfilled til plain text.
Excalidraw vs Canvas — sådan vælger du
Hvis du tænker i drawings — sketchy lines, hand-drawn feel, freeform-kompositioner — vælg Excalidraw. Excalidraw-pluginet renderer filen i samme æstetik, som du har set på whiteboards.
Hvis dine boards mest er rektangler med tekst forbundet af pile, og du bor i Obsidian som dit second brain — vælg Canvas. Canvas er native, åbner med ét klik og er syet sammen med vaultets backlinks og tags.
Nogle boards konverterer jeg til Excalidraw (hvor visual style betyder noget), andre til Canvas (hvor fart og native feel tæller). Repoet understøtter begge formater — du vælger ved kørsel.
Opsamling
Python 3, standard library only. Ingen pip install, ingen virtualenv, ingen node_modules. python3 miro_to_excalidraw.py 'BOARD_ID' 'output.excalidraw' — og filen er i dine hænder.
Repo: github.com/oleksiimazurenko/miro-to-obsidian. MIT-licens. PR-er velkomne — især for edge cases jeg endnu ikke er stødt på.
Lektien er større end Miro
SaaS lock-in er et stof. De første måneder er gratis. Efter et halvt år er det en vane. Efter et år lever dine data i et format, kun deres UI kan læse. Efter to betaler du Expert tier for at grave ud, hvad der allerede var dit.
Konklusionen er ikke »lad være med at bruge SaaS«. Konklusionen er: ethvert værktøj du lader blive load-bearing kræver en exit plan FØR du åbner det første gang. Spørgsmålet »hvordan kommer jeg ud herfra, når jeg skal« vejer lige så tungt som »hvor rar er UI'en«. Et værktøj uden plain-text-eksport eller åbent API er et værktøj med en skjult prismærkat, som du betaler om to år.
Obsidian-first ikke fordi Obsidian er perfekt. Men fordi plain markdown-filer er et format, der overlever Obsidian selv. På samme måde som en plain Excalidraw-JSON overlever selve pluginet. På samme måde som dette Python-script overlever Miro.