<?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: ArtemBobkin</title>
    <description>The latest articles on DEV Community by ArtemBobkin (@artembobkin).</description>
    <link>https://dev.to/artembobkin</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%2F4024576%2Fcba42789-0516-4756-9c36-d7a4c9127d80.png</url>
      <title>DEV Community: ArtemBobkin</title>
      <link>https://dev.to/artembobkin</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/artembobkin"/>
    <language>en</language>
    <item>
      <title>I built a native Swift + Metal map engine for SwiftUI with a globe view, and open-sourced it</title>
      <dc:creator>ArtemBobkin</dc:creator>
      <pubDate>Fri, 10 Jul 2026 22:38:45 +0000</pubDate>
      <link>https://dev.to/artembobkin/i-built-a-native-swift-metal-map-engine-for-swiftui-with-a-globe-view-and-open-sourced-it-41fp</link>
      <guid>https://dev.to/artembobkin/i-built-a-native-swift-metal-map-engine-for-swiftui-with-a-globe-view-and-open-sourced-it-41fp</guid>
      <description>&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%2Fzm19oik62ue4q97nzgsg.gif" 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%2Fzm19oik62ue4q97nzgsg.gif" alt="ImmersiveMap demo" width="600" height="352"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For the last few months I've been building &lt;a href="https://github.com/artembobkin/ImmersiveMap" rel="noopener noreferrer"&gt;&lt;strong&gt;ImmersiveMap&lt;/strong&gt;&lt;/a&gt; - a native Swift + Metal vector-tile map engine for SwiftUI apps. It renders on iOS (UIKit host) and native macOS (AppKit, not Catalyst) from the same SwiftUI code, with &lt;strong&gt;no WebView and no JavaScript bridge&lt;/strong&gt;. Today I open-sourced it under MIT.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it does
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A vector map that renders a &lt;strong&gt;globe&lt;/strong&gt; and a &lt;strong&gt;flat map&lt;/strong&gt;, and continuously morphs between the two as you zoom.&lt;/li&gt;
&lt;li&gt;Runs out of the box with a built-in tile provider - no token, no account.&lt;/li&gt;
&lt;li&gt;Pluggable providers: Mapbox vector tiles and OpenStreetMap / Shortbread.&lt;/li&gt;
&lt;li&gt;Labels, a starfield, avatar / live markers, and a two-tier disk + memory tile cache.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The part I had the most fun with
&lt;/h2&gt;

&lt;p&gt;Instead of hard-switching between a globe and a flat map at some zoom threshold, both render states are &lt;strong&gt;always&lt;/strong&gt; computed and the shaders morph between sphere and plane. There is no visible "switch" moment - the planet just unrolls.&lt;/p&gt;

&lt;p&gt;Rendering is also &lt;strong&gt;on-demand&lt;/strong&gt;: the display link is paused unless something actually needs to redraw (interaction, label fades, tile loads), so an idle map costs essentially nothing.&lt;/p&gt;

&lt;p&gt;Under the hood: MVT tiles decoded with swift-protobuf, polygons triangulated with earcut, MSDF text labels, a multi-pass render graph.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick start
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;SwiftUI&lt;/span&gt;
&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;ImmersiveMap&lt;/span&gt;

&lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;ContentView&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;@State&lt;/span&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;camera&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;ImmersiveMapCameraController&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;ImmersiveMapView&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cameraController&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;camera&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;enableCameraUIControls&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ignoresSafeArea&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That renders a map with no token required. The same code runs on iOS and macOS.&lt;/p&gt;

&lt;h2&gt;
  
  
  Honest status
&lt;/h2&gt;

&lt;p&gt;This is &lt;strong&gt;early alpha&lt;/strong&gt;. The public API is not stable, it's not production-ready, and it's not a drop-in replacement for Mapbox, MapLibre, or MapKit. It's a solo project, and I'm sharing it now to get feedback on the rendering architecture and to find out whether a native Metal map engine like this is useful to anyone besides me.&lt;/p&gt;

&lt;p&gt;Repo (MIT): &lt;strong&gt;&lt;a href="https://github.com/artembobkin/ImmersiveMap" rel="noopener noreferrer"&gt;https://github.com/artembobkin/ImmersiveMap&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Requirements: Swift 6, Xcode 16, iOS 18+, macOS 15+, a Metal-capable device.&lt;/p&gt;

&lt;p&gt;I'd love feedback - especially on the Metal pipeline and the globe/flat morph. Happy to answer anything in the comments.&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>swift</category>
      <category>ios</category>
      <category>metal</category>
    </item>
  </channel>
</rss>
