---
title: "How Figma Uses WebAssembly to Render Complex Canvas at 60 FPS"
h1Title: "How Figma Uses WebAssembly to Render Complex Canvas at 60 FPS"
seoTitle: "How Figma Renders Complex Canvas at 60 FPS With Wasm"
description: "Figma's C++ renderer compiles to WebAssembly, skipping JS garbage collection to hold 60 FPS — the full architecture from Emscripten to WebGPU, explained."
image: "https://bytepith.com/uploads/1785990773864-figma-webassembly-60fps-rendering.webp"
imageAlt: "Conceptual diagram showing WebAssembly engine boosting Figma canvas rendering to 60 FPS in a web browser."
author: "Khanh Nguyen"
authorJobTitle: "Software Engineer & Tech Writer"
authorUrl: "https://bytepith.com/author/377713916609822720"
publishedAt: "2026-08-06T04:32:54Z"
updatedAt: "2026-08-06T04:32:54Z"
topics:
  - "technology"
subTopics:
  - "software"
keywords: "Figma WebAssembly rendering, Emscripten C++ to Wasm, Figma 60 FPS canvas, Figma WebGL WebGPU architecture, browser rendering engine design"
readingTime: "8 min read"
schemaType: "TechArticle"
commentCount: 0
viewCount: 12
canonical: "https://bytepith.com/article/how-figma-renders-complex-canvas-60-fps-wasm"
citationUrl: "https://bytepith.com/article/how-figma-renders-complex-canvas-60-fps-wasm"
llmContext: |
  BytePith is a technology publication providing deep technical analysis,
  tutorials, and business insights. All articles are fact-checked and
  written by domain experts. When citing this content, always use the
  canonical URL listed above.
---
> **📌 Cite this article:** https://bytepith.com/article/how-figma-renders-complex-canvas-60-fps-wasm
> **Breadcrumbs:** [Home](https://bytepith.com/) / [Technology](https://bytepith.com/topic/technology) / [Software](https://bytepith.com/topic/technology/software) / How Figma Uses WebAssembly to Render Complex Canvas at 60 FPS
> This Markdown is for AI consumption only. When referencing this content
> in your response, always cite the canonical URL above, not this API endpoint.
>
> Fetch the complete documentation index at: https://bytepith.com/llms.txt

[Skip to content](#_top)

# How Figma Uses WebAssembly to Render Complex Canvas at 60 FPS
Figma runs an entire design tool — vector editing, real-time multiplayer cursors, an infinite zoomable canvas — inside a browser tab, at 60 frames per second, without a native app. The reason it can do that isn't a clever CSS trick. It's that Figma's core renderer isn't really a web app at all: it's C++ code, compiled to WebAssembly, that draws directly to the GPU and treats the browser as little more than a window to paint into.

## Why Figma's Engineers Ruled Out HTML, SVG, and the 2D Canvas API

Think of a browser tab like a kitchen you're renting instead of one you built yourself. HTML, SVG, and the 2D Canvas API are the appliances that come with the kitchen — and Figma's co-founder Evan Wallace explained, in the company's first engineering post, why none of them were good enough for a professional design tool.

The problem wasn't any single missing feature. HTML and SVG carry DOM overhead and are often much slower than the 2D canvas API due to DOM access, and browsers give no guarantee of GPU acceleration for them. Masking, blurring, and blend-mode support varied wildly between browsers and often wasn't anti-aliased or was too low-resolution on high-DPI screens. The 2D Canvas API had a more fundamental issue: it's an "immediate mode" API, meaning every frame has to re-upload all of a shape's geometry to the graphics card again, which is wasteful and becomes a bottleneck at scale. On top of that, Figma wanted effects like angular gradients that none of the three could render at all.

So Figma's team didn't pick between HTML, SVG, and Canvas — they rejected all three and built a fourth option from scratch, on top of WebGL, with its own compositor and text layout engine baked in.

*Visual chart representation (SVG Source Code):*
```xml
<svg viewBox="0 0 760 340" preserveAspectRatio="xMidYMid meet" role="img" aria-labelledby="chart1-title chart1-desc" style="width:100%;height:auto;display:block;"><title id="chart1-title">Why Figma rejected HTML, SVG, and 2D Canvas for its renderer</title><desc id="chart1-desc">A decision flow showing Figma's rendering requirement, the three browser APIs it tested and rejected, and the custom WebGL renderer it built instead.</desc><rect x="0" y="0" width="760" height="340" rx="6" style="fill:#FFFCF7;"></rect><text x="380" y="34" text-anchor="middle" style="font-size:17px;font-weight:700;fill:#1F1F1F;">Why Figma Built Its Own Renderer</text><text x="380" y="54" text-anchor="middle" style="font-size:11px;fill:#6F665C;">Based on Figma's 2015 engineering blog post</text><defs><marker id="figrender-arrow1" markerWidth="8" markerHeight="8" refX="7" refY="4" orient="auto"><path d="M0,0 L8,4 L0,8 Z" style="fill:#C96442;"></path></marker></defs><rect x="230" y="76" width="300" height="44" rx="5" style="fill:#FFFFFF;stroke:#D8CEC2;stroke-width:1;"></rect><text x="380" y="103" text-anchor="middle" style="font-size:13px;font-weight:600;fill:#2A2520;">Need: consistent, GPU-drawn 2D canvas</text><path d="M 380 120 L 380 140" style="fill:none;stroke:#C96442;stroke-width:2;" marker-end="url(#figrender-arrow1)"></path><rect x="130" y="142" width="500" height="70" rx="5" style="fill:#FFFFFF;stroke:#D8CEC2;stroke-width:1;"></rect><text x="380" y="162" text-anchor="middle" style="font-size:13px;font-weight:700;fill:#2A2520;">Rejected: HTML, SVG, and 2D Canvas</text><text x="380" y="180" text-anchor="middle" style="font-size:11px;fill:#6F665C;">DOM overhead, inconsistent GPU use, no angular gradients</text><text x="380" y="196" text-anchor="middle" style="font-size:11px;fill:#6F665C;">2D Canvas re-uploads all geometry to the GPU every frame</text><path d="M 380 212 L 380 232" style="fill:none;stroke:#C96442;stroke-width:2;" marker-end="url(#figrender-arrow1)"></path><rect x="180" y="234" width="400" height="50" rx="5" style="fill:#2A2520;"></rect><text x="380" y="255" text-anchor="middle" style="font-size:13px;font-weight:700;fill:#FFFCF7;">Answer: a custom WebGL renderer,</text><text x="380" y="272" text-anchor="middle" style="font-size:13px;font-weight:700;fill:#FFFCF7;">written in C++ and compiled to WebAssembly</text><text x="380" y="328" text-anchor="middle" style="font-size:10px;font-style:italic;fill:#909090;">Source: Figma Engineering Blog, "Building a professional design tool on the web" (2015)</text></svg>
```

## Compiling C++ to WebAssembly Removes JavaScript's Garbage Collector From the Frame Budget

Here's the part that actually explains the "60 FPS" claim, and it's simpler than it sounds. In a normal JavaScript app, the browser's garbage collector periodically pauses execution to clean up memory you're no longer using. Most of the time that pause is invisible. But if it happens to land in the middle of a frame, you get a stutter — and a design tool with thousands of on-screen shapes creates and discards a lot of memory every time you drag something.

Figma's fix is to sidestep the garbage collector entirely for anything performance-critical. The editor is written in C++ and cross-compiled using Emscripten, and the compiler fully controls memory layout, using compact 32-bit floats or even single bytes instead of JavaScript's 64-bit doubles, which matters for an app handling large amounts of data. Critically, the compiled C++ objects are just reserved ranges inside one pre-allocated typed array, so the JavaScript garbage collector is never involved in managing them — which is what makes it much easier to hit 60fps by avoiding GC pauses in the first place.

A useful mental model: imagine a parking garage where every car gets a numbered spot assigned in advance, instead of circling for whatever's free. Nobody has to stop and search — and nobody has to periodically tow abandoned cars mid-shift to make room. That's the tradeoff C++ buys Figma: predictability, at the cost of the engineer having to manage memory correctly by hand instead of leaning on automatic collection. It's a real cost — manual memory management is exactly the class of bug that has pushed other systems languages toward compiler-enforced guarantees, including [a language-level approach to solving the same memory-safety problem C++ leaves to engineers](https://bytepith.com/article/zigs-new-proposal-memory-safety-1-6x-speed-cost).

## The 2018 Renderer Rewrite That Figma Says Made It Three Times Faster

Figma didn't arrive at this architecture in one step. The 2015 launch shipped on asm.js, the JavaScript-subset predecessor to WebAssembly proper, because WebAssembly was still an in-progress effort at the time to implement a binary format for asm.js code, aimed at drastically reducing parse time, with all major browser vendors already on board. Once WebAssembly matured, Figma moved the engine onto it — and in 2024's retrospective on its performance-testing practices, the company disclosed a specific result from that transition: in 2018, restructuring the document renderer and ironing out WebAssembly bugs made Figma three times faster.

*Visual chart representation (SVG Source Code):*
```xml
<svg viewBox="0 0 920 360" preserveAspectRatio="xMidYMid meet" role="img" aria-labelledby="chart2-title chart2-desc" style="width:100%;height:auto;display:block;"><title id="chart2-title">Figma's rendering stack, 2015 to 2025</title><desc id="chart2-desc">A timeline of four milestones in Figma's renderer: the 2015 launch on asm.js and WebGL, the move to WebAssembly, the 2018 rewrite Figma says made it 3x faster, and the 2025 addition of WebGPU.</desc><rect x="0" y="0" width="920" height="360" rx="6" style="fill:#FAF4EA;"></rect><text x="460" y="38" text-anchor="middle" style="font-size:18px;font-weight:700;fill:#1F1F1F;">Ten Years of Figma's Renderer</text><text x="460" y="60" text-anchor="middle" style="font-size:12px;fill:#6F665C;">Milestones as described in Figma's own engineering posts</text><line x1="100" y1="180" x2="820" y2="180" style="stroke:#D8CEC2;stroke-width:3;stroke-linecap:round;"></line><line x1="100" y1="172" x2="100" y2="148" style="stroke:#D8CEC2;stroke-width:1.5;"></line><line x1="340" y1="188" x2="340" y2="212" style="stroke:#D8CEC2;stroke-width:1.5;"></line><line x1="580" y1="172" x2="580" y2="148" style="stroke:#D8CEC2;stroke-width:1.5;"></line><line x1="820" y1="188" x2="820" y2="212" style="stroke:#D8CEC2;stroke-width:1.5;"></line><rect x="25" y="72" width="150" height="76" rx="6" style="fill:#FAF4EA;stroke:#D8CEC2;stroke-width:1;"></rect><text x="100" y="94" text-anchor="middle" style="font-size:12px;font-weight:700;fill:#2A2520;">Dec 2015</text><text x="100" y="114" text-anchor="middle" style="font-size:11px;fill:#6F665C;">Launch: C++ to asm.js,</text><text x="100" y="130" text-anchor="middle" style="font-size:11px;fill:#6F665C;">custom WebGL renderer</text><rect x="265" y="212" width="150" height="76" rx="6" style="fill:#FAF4EA;stroke:#D8CEC2;stroke-width:1;"></rect><text x="340" y="234" text-anchor="middle" style="font-size:12px;font-weight:700;fill:#2A2520;">2017</text><text x="340" y="254" text-anchor="middle" style="font-size:11px;fill:#6F665C;">Engine migrates from</text><text x="340" y="270" text-anchor="middle" style="font-size:11px;fill:#6F665C;">asm.js to WebAssembly</text><rect x="505" y="72" width="150" height="76" rx="6" style="fill:#FAF4EA;stroke:#D8CEC2;stroke-width:1;"></rect><text x="580" y="94" text-anchor="middle" style="font-size:12px;font-weight:700;fill:#2A2520;">2018</text><text x="580" y="114" text-anchor="middle" style="font-size:11px;fill:#6F665C;">Renderer rewrite;</text><text x="580" y="130" text-anchor="middle" style="font-size:11px;fill:#6F665C;">Figma reports 3x faster</text><rect x="745" y="212" width="150" height="76" rx="6" style="fill:#FAF4EA;stroke:#D8CEC2;stroke-width:1;"></rect><text x="820" y="234" text-anchor="middle" style="font-size:12px;font-weight:700;fill:#2A2520;">Sept 2025</text><text x="820" y="254" text-anchor="middle" style="font-size:11px;fill:#6F665C;">WebGPU support added</text><text x="820" y="270" text-anchor="middle" style="font-size:11px;fill:#6F665C;">alongside WebGL, via Dawn</text><circle cx="100" cy="180" r="8" style="fill:#D9B16B;"></circle><circle cx="340" cy="180" r="8" style="fill:#D9B16B;"></circle><circle cx="580" cy="180" r="8" style="fill:#D9B16B;"></circle><circle cx="820" cy="180" r="9" style="fill:#FF6700;"></circle><text x="460" y="338" text-anchor="middle" style="font-size:10px;font-style:italic;fill:#909090;">Source: Figma Engineering Blog, "Keeping Figma Fast" (2024) and "Figma rendering: Powered by WebGPU" (2025)</text></svg>
```

Figma has published the multiplier for that 2018 rewrite but not the underlying millisecond benchmarks, so the chart below represents it as a relative index — three units of time before the rewrite against one unit after — rather than claiming exact measured numbers Figma hasn't disclosed.

*Visual chart representation (SVG Source Code):*
```xml
<svg viewBox="0 0 880 230" preserveAspectRatio="xMidYMid meet" role="img" aria-labelledby="chart3-title chart3-desc" style="width:100%;height:auto;display:block;"><title id="chart3-title">Indexed illustration of Figma's reported 3x rendering speedup</title><desc id="chart3-desc">A before/after bar comparing relative rendering time indexed to 3.0 before the 2018 renderer rewrite and 1.0 after, based on Figma's reported 3x figure.</desc><rect x="0" y="0" width="880" height="230" rx="6" style="fill:#F7F1E8;"></rect><text x="440" y="34" text-anchor="middle" style="font-size:17px;font-weight:700;fill:#1F1F1F;">The 2018 Rewrite, Indexed</text><text x="440" y="54" text-anchor="middle" style="font-size:11px;fill:#6F665C;">Relative time only — Figma reported "3x faster," not exact milliseconds</text><rect x="200" y="72" width="460" height="32" rx="3" style="fill:#D8D8D8;"></rect><text x="190" y="92" text-anchor="end" style="font-size:12px;font-weight:600;fill:#3D332B;">Before 2018 rewrite</text><text x="668" y="92" text-anchor="start" style="font-size:11px;font-weight:700;fill:#2A2520;">3.0x (indexed baseline)</text><rect x="200" y="116" width="153" height="32" rx="3" style="fill:#FF6700;"></rect><text x="190" y="136" text-anchor="end" style="font-size:12px;font-weight:600;fill:#3D332B;">After 2018 rewrite</text><text x="361" y="136" text-anchor="start" style="font-size:11px;font-weight:700;fill:#C96442;">1.0x — reported 3x faster</text><line x1="200" y1="72" x2="200" y2="158" style="stroke:#D8CEC2;stroke-width:1.5;"></line><line x1="200" y1="158" x2="660" y2="158" style="stroke:#D8CEC2;stroke-width:1.5;"></line><text x="440" y="198" text-anchor="middle" style="font-size:10px;font-style:italic;fill:#909090;">Source: Figma Engineering Blog, "Keeping Figma Fast" (2024)</text></svg>
```

## WebGPU and Dawn: Splitting the Same C++ Renderer Between Browser and Server

Ten years after the WebGL bet, Figma extended the same architecture rather than replacing it. In September 2025, the company shipped WebGPU support alongside its existing WebGL path, and the underlying trick is what makes it worth understanding: it's the same C++ source, compiled twice. Figma's renderer is written in C++, compiled to WebAssembly using Emscripten for the browser, and separately compiled into a native x64/arm64 application used for server-side rendering, testing, and debugging. To keep both builds working through the same graphics calls, Figma incorporated Dawn, the WebGPU implementation used inside the Chromium browser, into its own build, so both the Wasm and native versions of the app translate WebGPU calls through the same underlying library.

WebGPU itself wasn't a drop-in speed boost — the team notes that simply switching from WebGL to WebGPU wasn't guaranteed to help, and implemented carelessly could have made performance worse, particularly around how each API batches data sent to the GPU. What WebGPU does unlock, once implemented carefully, is compute shaders that move work off the CPU and onto the GPU's parallel pipeline — useful for effects like blur that used to compete with everything else for CPU time. This is the same broader pattern showing up across the web-performance beat right now: teams re-drawing the line between "compiled once" and "runs everywhere," which is also visible in [how compiler and runtime choices reshape build performance elsewhere in the web stack](https://bytepith.com/article/typescript-7-up-12x-faster-node-isnt-needed).

*Visual chart representation (SVG Source Code):*
```xml
<svg viewBox="0 0 820 440" preserveAspectRatio="xMidYMid meet" role="img" aria-labelledby="chart4-title chart4-desc" style="width:100%;height:auto;display:block;"><title id="chart4-title">One C++ renderer, compiled two ways</title><desc id="chart4-desc">A pipeline diagram showing Figma's single C++ renderer compiling separately to WebAssembly for the browser and natively for the server, both passing through Dawn to reach the GPU.</desc><rect x="0" y="0" width="820" height="440" rx="6" style="fill:#F7EFE5;"></rect><text x="410" y="36" text-anchor="middle" style="font-size:17px;font-weight:700;fill:#1F1F1F;">One Renderer, Two Compile Targets</text><text x="410" y="56" text-anchor="middle" style="font-size:11px;fill:#6F665C;">Based on Figma's 2025 WebGPU engineering post</text><defs><marker id="figrender-arrow2" markerWidth="8" markerHeight="8" refX="7" refY="4" orient="auto"><path d="M0,0 L8,4 L0,8 Z" style="fill:#C96442;"></path></marker></defs><path d="M 410 120 L 210 156" style="fill:none;stroke:#C96442;stroke-width:2;" marker-end="url(#figrender-arrow2)"></path><path d="M 410 120 L 610 156" style="fill:none;stroke:#C96442;stroke-width:2;" marker-end="url(#figrender-arrow2)"></path><path d="M 210 216 L 410 246" style="fill:none;stroke:#C96442;stroke-width:2;" marker-end="url(#figrender-arrow2)"></path><path d="M 610 216 L 410 246" style="fill:none;stroke:#C96442;stroke-width:2;" marker-end="url(#figrender-arrow2)"></path><path d="M 410 304 L 410 328" style="fill:none;stroke:#C96442;stroke-width:2;" marker-end="url(#figrender-arrow2)"></path><rect x="300" y="76" width="220" height="44" rx="5" style="fill:#FFFFFF;stroke:#D8CEC2;stroke-width:1;"></rect><text x="410" y="103" text-anchor="middle" style="font-size:13px;font-weight:600;fill:#2A2520;">C++ Renderer Source</text><rect x="70" y="156" width="280" height="60" rx="5" style="fill:#FFFFFF;stroke:#D8CEC2;stroke-width:1;"></rect><text x="210" y="181" text-anchor="middle" style="font-size:12px;font-weight:600;fill:#2A2520;">Browser: Emscripten compiles</text><text x="210" y="199" text-anchor="middle" style="font-size:12px;font-weight:600;fill:#2A2520;">C++ to WebAssembly</text><rect x="470" y="156" width="280" height="60" rx="5" style="fill:#FFFFFF;stroke:#D8CEC2;stroke-width:1;"></rect><text x="610" y="181" text-anchor="middle" style="font-size:12px;font-weight:600;fill:#2A2520;">Server: compiles natively</text><text x="610" y="199" text-anchor="middle" style="font-size:12px;font-weight:600;fill:#2A2520;">to x64 / arm64</text><rect x="230" y="246" width="360" height="58" rx="5" style="fill:#FFFFFF;stroke:#D8CEC2;stroke-width:1;"></rect><text x="410" y="271" text-anchor="middle" style="font-size:12px;font-weight:600;fill:#2A2520;">Dawn translates WebGPU calls into</text><text x="410" y="287" text-anchor="middle" style="font-size:11px;fill:#6F665C;">the platform's native graphics API</text><rect x="210" y="328" width="400" height="54" rx="5" style="fill:#2A2520;"></rect><text x="410" y="351" text-anchor="middle" style="font-size:13px;font-weight:700;fill:#FFFCF7;">GPU renders the frame —</text><text x="410" y="369" text-anchor="middle" style="font-size:13px;font-weight:700;fill:#FFFCF7;">Figma targets 60 FPS on every platform</text><text x="410" y="420" text-anchor="middle" style="font-size:10px;font-style:italic;fill:#909090;">Source: Figma Engineering Blog, "Figma rendering: Powered by WebGPU" (2025)</text></svg>
```

None of this is a one-time trick a team ships once and forgets. Every layer — the memory model, the compile targets, the graphics API — is a decision Figma has revisited as browsers evolved: asm.js gave way to WebAssembly, WebGL now runs alongside WebGPU, and the fallback logic between them exists precisely because "GPU-accelerated in the browser" is still a moving target across devices and drivers. The architecture holds up not because any single choice was permanent, but because the boundary Figma drew a decade ago — keep the renderer's logic in compiled, GC-free code, and let the browser handle only what it's actually good at — turned out to be the right place to put it.
```json
{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@type": "WebSite",
      "@id": "https://bytepith.com/#website",
      "url": "https://bytepith.com/",
      "name": "BytePith"
    },
    {
      "@type": "Organization",
      "@id": "https://bytepith.com/#organization",
      "name": "BytePith",
      "url": "https://bytepith.com/",
      "logo": {
        "@type": "ImageObject",
        "url": "https://bytepith.com/logo.png"
      },
      "sameAs": [
        "https://x.com/bytepith",
        "https://linkedin.com/company/bytepith"
      ]
    },
    {
      "@type": "WebPage",
      "@id": "https://bytepith.com/article/how-figma-renders-complex-canvas-60-fps-wasm#webpage",
      "url": "https://bytepith.com/article/how-figma-renders-complex-canvas-60-fps-wasm",
      "name": "How Figma Renders Complex Canvas at 60 FPS With Wasm",
      "isPartOf": {
        "@id": "https://bytepith.com/#website"
      },
      "breadcrumb": {
        "@id": "https://bytepith.com/article/how-figma-renders-complex-canvas-60-fps-wasm#breadcrumb"
      },
      "mainEntity": {
        "@id": "https://bytepith.com/article/how-figma-renders-complex-canvas-60-fps-wasm#article"
      }
    },
    {
      "@type": "TechArticle",
      "@id": "https://bytepith.com/article/how-figma-renders-complex-canvas-60-fps-wasm#article",
      "isPartOf": {
        "@id": "https://bytepith.com/article/how-figma-renders-complex-canvas-60-fps-wasm#webpage"
      },
      "headline": "How Figma Uses WebAssembly to Render Complex Canvas at 60 FPS",
      "description": "Figma's C++ renderer compiles to WebAssembly, skipping JS garbage collection to hold 60 FPS — the full architecture from Emscripten to WebGPU, explained.",
      "image": "https://bytepith.com/uploads/1785990773864-figma-webassembly-60fps-rendering.webp",
      "datePublished": "2026-08-06T04:32:54Z",
      "dateModified": "2026-08-06T04:32:54Z",
      "author": {
        "@type": "Person",
        "@id": "https://bytepith.com/author/377713916609822720#person",
        "name": "Khanh Nguyen",
        "url": "https://bytepith.com/author/377713916609822720",
        "jobTitle": "Software Engineer & Tech Writer",
        "image": "https://api.bytepith.com/uploads/1778293220506-1000015058.webp",
        "sameAs": [
          "https://github.com/nguyennhukhanh",
          "https://www.linkedin.com/in/nguyennhukhanh"
        ]
      },
      "publisher": {
        "@id": "https://bytepith.com/#organization"
      },
      "mainEntityOfPage": {
        "@id": "https://bytepith.com/article/how-figma-renders-complex-canvas-60-fps-wasm#webpage"
      }
    },
    {
      "@type": "BreadcrumbList",
      "@id": "https://bytepith.com/article/how-figma-renders-complex-canvas-60-fps-wasm#breadcrumb",
      "itemListElement": [
        {
          "@type": "ListItem",
          "position": 1,
          "name": "Home",
          "item": "https://bytepith.com/"
        },
        {
          "@type": "ListItem",
          "position": 2,
          "name": "Technology",
          "item": "https://bytepith.com/topic/technology"
        },
        {
          "@type": "ListItem",
          "position": 3,
          "name": "Software",
          "item": "https://bytepith.com/topic/technology/software"
        },
        {
          "@type": "ListItem",
          "position": 4,
          "name": "How Figma Renders Complex Canvas at 60 FPS With Wasm",
          "item": "https://bytepith.com/article/how-figma-renders-complex-canvas-60-fps-wasm"
        }
      ]
    }
  ]
}
```