252 lines
21 KiB
HTML
252 lines
21 KiB
HTML
{{template "layout" .}}
|
|
{{define "title"}}WP Packages vs WPackagist — Faster, Independent WordPress Composer Repository{{end}}
|
|
{{define "meta_seo"}}
|
|
<meta name="description" content="Compare WP Packages and WPackagist. WP Packages is 17x faster, updates every 5 minutes, and is fully open-source.">
|
|
{{if .AppURL}}<link rel="canonical" href="{{.AppURL}}/wp-packages-vs-wpackagist">{{end}}
|
|
{{end}}
|
|
{{define "json_ld"}}{{end}}
|
|
{{define "og_meta"}}
|
|
<meta property="og:title" content="WP Packages vs WPackagist">
|
|
<meta property="og:description" content="WP Packages is 17x faster, updates every 5 minutes, and is fully open-source.">
|
|
{{if .OGImage}}<meta property="og:image" content="{{.OGImage}}">{{end}}
|
|
{{if .AppURL}}<meta property="og:url" content="{{.AppURL}}/wp-packages-vs-wpackagist">{{end}}
|
|
<meta property="og:type" content="website">
|
|
<meta name="twitter:card" content="summary_large_image">
|
|
<meta name="twitter:title" content="WP Packages vs WPackagist">
|
|
<meta name="twitter:description" content="WP Packages is 17x faster, updates every 5 minutes, and is fully open-source.">
|
|
{{if .OGImage}}<meta name="twitter:image" content="{{.OGImage}}">{{end}}
|
|
{{end}}
|
|
{{define "content"}}
|
|
<section class="relative border-b border-gray-200/50">
|
|
<div class="absolute inset-0 bg-gradient-to-b from-brand-lightest/40 to-transparent"></div>
|
|
<div class="relative mx-auto max-w-3xl px-4 sm:px-6 lg:px-8 pt-16 pb-12 sm:pt-24 sm:pb-16 text-center">
|
|
<h1 class="text-3xl sm:text-4xl lg:text-5xl font-bold tracking-tight text-gray-900 mb-4 text-balance">WP Packages <span class="text-brand-primary">vs</span> WPackagist</h1>
|
|
<p class="text-lg text-gray-500 max-w-xl mx-auto text-balance">WP Packages is 17x faster, updates every 5 minutes, and is fully open-source.</p>
|
|
</div>
|
|
</section>
|
|
|
|
<article class="mx-auto max-w-3xl px-4 sm:px-6 lg:px-8 py-12 sm:py-16">
|
|
|
|
<div class="prose prose-gray max-w-none">
|
|
|
|
<p class="text-lg text-gray-600 leading-relaxed mb-10">For years, WPackagist was the go-to Composer repository for WordPress plugins and themes. In March 2026, WPackagist was acquired by WP Engine, a private-equity backed company. Tooling this central to the WordPress Composer workflow shouldn't be owned by a single corporation — it should be independent and community-funded.</p>
|
|
|
|
<h2 class="text-2xl font-bold text-gray-900 mb-6">How they compare</h2>
|
|
|
|
<div class="rounded-xl border border-gray-200/60 overflow-hidden mb-12">
|
|
<table class="w-full text-sm">
|
|
<thead class="bg-gray-50/50">
|
|
<tr>
|
|
<th class="text-left px-4 py-3 font-medium text-gray-500 w-1/3"></th>
|
|
<th class="text-left px-4 py-3 font-semibold text-brand-primary">WP Packages</th>
|
|
<th class="text-left px-4 py-3 font-medium text-gray-500">WPackagist</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="border-t border-gray-200/40">
|
|
<td class="px-4 py-3 font-medium text-gray-700">Ownership</td>
|
|
<td class="px-4 py-3 text-gray-600">Independent, maintained by <a href="https://roots.io" class="text-brand-primary hover:underline">Roots</a></td>
|
|
<td class="px-4 py-3 text-gray-600">WP Engine (private equity)</td>
|
|
</tr>
|
|
<tr class="border-t border-gray-200/40">
|
|
<td class="px-4 py-3 font-medium text-gray-700">Open source</td>
|
|
<td class="px-4 py-3 text-gray-600">Fully open source — <a href="https://github.com/roots/wp-packages" class="text-brand-primary hover:underline">contributions welcome</a></td>
|
|
<td class="px-4 py-3 text-gray-600">Partially open source — incomplete source (<a href="https://github.com/wpengine/wpackagist/issues/557" class="text-brand-primary hover:underline">#557</a>), and currently doesn't reflect the live site (<a href="https://github.com/wpengine/wpackagist/issues/556" class="text-brand-primary hover:underline">#556</a>)</td>
|
|
</tr>
|
|
<tr class="border-t border-gray-200/40">
|
|
<td class="px-4 py-3 font-medium text-gray-700">Funding</td>
|
|
<td class="px-4 py-3 text-gray-600">Community-funded via <a href="https://github.com/sponsors/roots" class="text-brand-primary hover:underline">GitHub Sponsors</a></td>
|
|
<td class="px-4 py-3 text-gray-600">Corporate-funded</td>
|
|
</tr>
|
|
<tr class="border-t border-gray-200/40">
|
|
<td class="px-4 py-3 font-medium text-gray-700">Package naming</td>
|
|
<td class="px-4 py-3 text-gray-600"><code class="text-xs font-mono bg-gray-100 px-1.5 py-0.5 rounded border border-gray-200/40">wp-plugin/*</code> <code class="text-xs font-mono bg-gray-100 px-1.5 py-0.5 rounded border border-gray-200/40">wp-theme/*</code></td>
|
|
<td class="px-4 py-3 text-gray-600"><code class="text-xs font-mono bg-gray-100 px-1.5 py-0.5 rounded border border-gray-200/40">wpackagist-plugin/*</code> <code class="text-xs font-mono bg-gray-100 px-1.5 py-0.5 rounded border border-gray-200/40">wpackagist-theme/*</code></td>
|
|
</tr>
|
|
<tr class="border-t border-gray-200/40">
|
|
<td class="px-4 py-3 font-medium text-gray-700">Package metadata</td>
|
|
<td class="px-4 py-3 text-gray-600">Includes plugin/theme authors, description, homepage, and support links in Composer metadata</td>
|
|
<td class="px-4 py-3 text-gray-600">Missing — <a href="https://github.com/outlandishideas/wpackagist/issues/305" class="text-brand-primary hover:underline">requested since 2020</a></td>
|
|
</tr>
|
|
<tr class="border-t border-gray-200/40">
|
|
<td class="px-4 py-3 font-medium text-gray-700">Update frequency</td>
|
|
<td class="px-4 py-3 text-gray-600">Every 5 minutes</td>
|
|
<td class="px-4 py-3 text-gray-600">~1.5 hours (estimated — infrastructure is not open source)</td>
|
|
</tr>
|
|
<tr class="border-t border-gray-200/40">
|
|
<td class="px-4 py-3 font-medium text-gray-700">Governance</td>
|
|
<td class="px-4 py-3 text-gray-600">Open roadmap, community collaboration</td>
|
|
<td class="px-4 py-3 text-gray-600">Corporate decision-making</td>
|
|
</tr>
|
|
<tr class="border-t border-gray-200/40">
|
|
<td class="px-4 py-3 font-medium text-gray-700">Untagged plugin installs</td>
|
|
<td class="px-4 py-3 text-gray-600">Pinned to SVN revision — <code class="text-xs font-mono bg-gray-100 px-1.5 py-0.5 rounded border border-gray-200/40">composer.lock</code> is reproducible</td>
|
|
<td class="px-4 py-3 text-gray-600">Mutable trunk zip with cache-busting timestamp — <code class="text-xs font-mono bg-gray-100 px-1.5 py-0.5 rounded border border-gray-200/40">composer.lock</code> is not reproducible — <strong>this can cause unexpected plugin updates</strong></td>
|
|
</tr>
|
|
<tr class="border-t border-gray-200/40">
|
|
<td class="px-4 py-3 font-medium text-gray-700">Install statistics</td>
|
|
<td class="px-4 py-3 text-gray-600">Per-package install stats — transparency for the community and package authors to see how many times their packages are installed via Composer</td>
|
|
<td class="px-4 py-3 text-gray-600">No install statistics</td>
|
|
</tr>
|
|
<tr class="border-t border-gray-200/40">
|
|
<td class="px-4 py-3 font-medium text-gray-700">Public status page</td>
|
|
<td class="px-4 py-3 text-gray-600">Real-time <a href="/status" class="text-brand-primary hover:underline">status page</a> with build history, package changes, and closure tracking</td>
|
|
<td class="px-4 py-3 text-gray-600">No status page</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<h2 class="text-2xl font-bold text-gray-900 mb-6">Performance</h2>
|
|
|
|
<p class="text-gray-600 mb-6 leading-relaxed">WP Packages supports Composer v2's <code class="text-sm font-mono bg-gray-100 px-1.5 py-0.5 rounded border border-gray-200/40">metadata-url</code> protocol, which lets Composer fetch metadata for only the packages it needs. WPackagist still uses the older <code class="text-sm font-mono bg-gray-100 px-1.5 py-0.5 rounded border border-gray-200/40">provider-includes</code> approach, which forces Composer to download large index files containing metadata for thousands of packages before it can resolve your dependencies.</p>
|
|
|
|
<h3 class="text-lg font-semibold text-gray-900 mb-4">Composer resolve times</h3>
|
|
|
|
<p class="text-gray-500 text-sm mb-4">Cold resolve (no cache) — lower is better.</p>
|
|
|
|
<div class="rounded-xl border border-gray-200/60 overflow-hidden mb-8">
|
|
<table class="w-full text-sm">
|
|
<thead class="bg-gray-50/50">
|
|
<tr>
|
|
<th class="text-left px-4 py-3 font-medium text-gray-500">Plugins</th>
|
|
<th class="text-left px-4 py-3 font-semibold text-brand-primary">WP Packages</th>
|
|
<th class="text-left px-4 py-3 font-medium text-gray-500">WPackagist</th>
|
|
<th class="text-left px-4 py-3 font-medium text-gray-500">Speedup</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="border-t border-gray-200/40">
|
|
<td class="px-4 py-3 font-medium text-gray-700">10 plugins</td>
|
|
<td class="px-4 py-3 text-brand-primary font-medium">0.7s</td>
|
|
<td class="px-4 py-3 text-gray-600">12.3s</td>
|
|
<td class="px-4 py-3 text-gray-600">17x faster</td>
|
|
</tr>
|
|
<tr class="border-t border-gray-200/40">
|
|
<td class="px-4 py-3 font-medium text-gray-700">20 plugins</td>
|
|
<td class="px-4 py-3 text-brand-primary font-medium">1.1s</td>
|
|
<td class="px-4 py-3 text-gray-600">19.0s</td>
|
|
<td class="px-4 py-3 text-gray-600">17x faster</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<h3 class="text-lg font-semibold text-gray-900 mb-4">Metadata & caching</h3>
|
|
|
|
<div class="rounded-xl border border-gray-200/60 overflow-hidden mb-8">
|
|
<table class="w-full text-sm">
|
|
<thead class="bg-gray-50/50">
|
|
<tr>
|
|
<th class="text-left px-4 py-3 font-medium text-gray-500"></th>
|
|
<th class="text-left px-4 py-3 font-semibold text-brand-primary">WP Packages</th>
|
|
<th class="text-left px-4 py-3 font-medium text-gray-500">WPackagist</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="border-t border-gray-200/40">
|
|
<td class="px-4 py-3 font-medium text-gray-700">Composer v2 metadata-url</td>
|
|
<td class="px-4 py-3 text-brand-primary font-medium">Yes</td>
|
|
<td class="px-4 py-3 text-gray-600">No</td>
|
|
</tr>
|
|
<tr class="border-t border-gray-200/40">
|
|
<td class="px-4 py-3 font-medium text-gray-700">Metadata changes feed (<code class="text-xs font-mono bg-gray-100 px-1.5 py-0.5 rounded border border-gray-200/40">metadata-changes-url</code>)</td>
|
|
<td class="px-4 py-3 text-brand-primary font-medium">Yes</td>
|
|
<td class="px-4 py-3 text-gray-600">No</td>
|
|
</tr>
|
|
<tr class="border-t border-gray-200/40">
|
|
<td class="px-4 py-3 font-medium text-gray-700">CDN caching</td>
|
|
<td class="px-4 py-3 text-gray-600"><code class="text-xs font-mono bg-gray-100 px-1.5 py-0.5 rounded border border-gray-200/40">public, max-age=300</code></td>
|
|
<td class="px-4 py-3 text-gray-600"><code class="text-xs font-mono bg-gray-100 px-1.5 py-0.5 rounded border border-gray-200/40">no-cache, private</code></td>
|
|
</tr>
|
|
<tr class="border-t border-gray-200/40">
|
|
<td class="px-4 py-3 font-medium text-gray-700">Per-package files</td>
|
|
<td class="px-4 py-3 text-gray-600">Immutable, content-addressed, cached indefinitely</td>
|
|
<td class="px-4 py-3 text-gray-600">Not content-addressed</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<p class="text-gray-500 text-sm mb-12">Benchmarks run from a single location using Composer 2.7+. Results may vary by region and network conditions. Benchmark scripts are <a href="https://github.com/roots/wp-packages/tree/main/benchmarks" class="text-brand-primary hover:underline">open source</a>.</p>
|
|
|
|
<h2 class="text-2xl font-bold text-gray-900 mb-4">The case for independence</h2>
|
|
|
|
<p class="text-gray-600 mb-4 leading-relaxed">WPackagist was originally built and maintained by <a href="https://outlandish.com/" class="text-brand-primary hover:underline">Outlandish</a>, who operated the service for over a decade. In its later years, the project suffered from neglect — slow updates, limited maintenance, and no meaningful community input into its direction.</p>
|
|
|
|
<p class="text-gray-600 mb-4 leading-relaxed">Its acquisition by WP Engine raises important questions. When infrastructure this foundational to the WordPress developer workflow is controlled by a single corporation, the community loses its voice. Decisions about availability, pricing, and direction are made in boardrooms, not in the open.</p>
|
|
|
|
<p class="text-gray-600 mb-8 leading-relaxed">It's also unclear whether WPackagist remains truly open source. The <a href="https://github.com/outlandishideas/wpackagist" class="text-brand-primary hover:underline">GitHub repository</a> no longer reflects the live website, making it difficult for the community to audit, contribute to, or fork the project.</p>
|
|
|
|
<h2 class="text-2xl font-bold text-gray-900 mb-4">Built by Roots, maintained since 2011</h2>
|
|
|
|
<p class="text-gray-600 mb-4 leading-relaxed">WP Packages is built by <a href="https://roots.io" class="text-brand-primary hover:underline">Roots</a>, the team behind <a href="https://roots.io/bedrock/" class="text-brand-primary hover:underline">Bedrock</a>, <a href="https://roots.io/sage/" class="text-brand-primary hover:underline">Sage</a>, <a href="https://roots.io/trellis/" class="text-brand-primary hover:underline">Trellis</a>, and <a href="https://roots.io/acorn/" class="text-brand-primary hover:underline">Acorn</a>. Since 2011, Roots has been continuously improving and maintaining open source WordPress tooling. We pioneered the use of Composer in WordPress development and have a proven track record of long-term commitment to the ecosystem.</p>
|
|
|
|
<p class="text-gray-600 mb-4 leading-relaxed">WP Packages is <a href="https://github.com/roots/wp-packages" class="text-brand-primary hover:underline">fully open source</a> and designed for community collaboration. Every line of code is public, contributions are welcome, and the project's direction is shaped by the developers who use it.</p>
|
|
|
|
<p class="text-gray-600 mb-8 leading-relaxed">The repository includes everything needed to run your own instance: the application code, documentation on how it all works, and the full Ansible setup for deploying to production. Anyone can fork it and build their own WordPress Composer repository.</p>
|
|
|
|
<h2 class="text-2xl font-bold text-gray-900 mb-4">Community-funded, community-driven</h2>
|
|
|
|
<p class="text-gray-600 mb-4 leading-relaxed">Unlike corporate-backed alternatives, WP Packages is funded entirely by the community through <a href="https://github.com/sponsors/roots" class="text-brand-primary hover:underline">GitHub Sponsors</a>. Your sponsorship directly supports the infrastructure, development, and maintenance of WP Packages and the broader Roots ecosystem.</p>
|
|
|
|
<p class="text-gray-600 mb-8 leading-relaxed">Sponsoring Roots means investing in independent, community-funded WordPress tooling that serves developers — not shareholders.</p>
|
|
|
|
<div class="rounded-xl border border-brand-primary/20 bg-brand-lightest/30 p-6 sm:p-8 text-center mb-8">
|
|
<h3 class="text-lg font-bold text-gray-900 mb-2">Support independent WordPress tooling</h3>
|
|
<p class="text-gray-600 mb-5 text-sm">Help us keep WP Packages independent and freely available for every WordPress developer.</p>
|
|
<a href="https://github.com/sponsors/roots" class="inline-flex items-center rounded-lg bg-brand-primary px-5 py-2.5 text-sm font-medium text-white hover:bg-brand-primary/85 transition-colors">Sponsor Roots on GitHub</a>
|
|
</div>
|
|
|
|
<h2 class="text-2xl font-bold text-gray-900 mb-4">Migrating from WPackagist</h2>
|
|
|
|
<p class="text-gray-600 mb-4 leading-relaxed">Switching from WPackagist takes one command. Use the <a href="https://github.com/roots/wp-packages/blob/main/scripts/migrate-from-wpackagist.sh" class="text-brand-primary hover:underline">migration script</a> to automatically update your <code class="text-sm font-mono bg-gray-100 px-1.5 py-0.5 rounded border border-gray-200/40">composer.json</code>:</p>
|
|
<div class="flex items-center gap-3 rounded-xl border border-gray-200/60 bg-gray-100/30 px-4 py-2.5 cursor-pointer hover:border-gray-300 transition-colors mb-8" onclick="copyCmd(this,'curl -sO https://raw.githubusercontent.com/roots/wp-packages/main/scripts/migrate-from-wpackagist.sh && bash migrate-from-wpackagist.sh')">
|
|
<span class="text-gray-500 text-sm font-mono select-none shrink-0">$</span>
|
|
<code class="flex-1 text-sm font-mono text-gray-900 truncate">curl -sO https://raw.githubusercontent.com/roots/wp-packages/main/scripts/migrate-from-wpackagist.sh && bash migrate-from-wpackagist.sh</code>
|
|
<button aria-label="Copy to clipboard" class="shrink-0 text-gray-400 hover:text-gray-900 transition-colors cursor-pointer">
|
|
<svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M15.666 3.888A2.25 2.25 0 0 0 13.5 2.25h-3c-1.03 0-1.9.693-2.166 1.638m7.332 0c.055.194.084.4.084.612v0a.75.75 0 0 1-.75.75H9.75a.75.75 0 0 1-.75-.75v0c0-.212.03-.418.084-.612m7.332 0c.646.049 1.288.11 1.927.184 1.1.128 1.907 1.077 1.907 2.185V19.5a2.25 2.25 0 0 1-2.25 2.25H6.75A2.25 2.25 0 0 1 4.5 19.5V6.257c0-1.108.806-2.057 1.907-2.185a48.208 48.208 0 0 1 1.927-.184"/></svg>
|
|
</button>
|
|
</div>
|
|
|
|
<h3 class="text-lg font-bold mb-6">Manually migrate</h3>
|
|
<div class="space-y-4 mb-4">
|
|
<div class="flex items-start gap-4">
|
|
<div class="flex w-7 h-7 shrink-0 items-center justify-center rounded-full bg-brand-primary text-white text-xs font-bold">1</div>
|
|
<div class="min-w-0">
|
|
<p class="text-gray-600 mb-2 leading-7">Remove WPackagist packages:</p>
|
|
<div class="flex items-center gap-3 px-4 py-2.5 rounded-xl border border-gray-200/60 bg-gray-100/30 cursor-pointer hover:border-gray-300 transition-colors" onclick="copyCmd(this,'composer remove wpackagist-plugin/woocommerce')">
|
|
<span class="text-gray-500 text-sm font-mono select-none shrink-0">$</span>
|
|
<code class="flex-1 text-sm font-mono text-gray-900 truncate">composer remove wpackagist-plugin/woocommerce</code>
|
|
<button aria-label="Copy to clipboard" class="shrink-0 text-gray-400 hover:text-gray-900 transition-colors cursor-pointer"><svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M15.666 3.888A2.25 2.25 0 0 0 13.5 2.25h-3c-1.03 0-1.9.693-2.166 1.638m7.332 0c.055.194.084.4.084.612v0a.75.75 0 0 1-.75.75H9.75a.75.75 0 0 1-.75-.75v0c0-.212.03-.418.084-.612m7.332 0c.646.049 1.288.11 1.927.184 1.1.128 1.907 1.077 1.907 2.185V19.5a2.25 2.25 0 0 1-2.25 2.25H6.75A2.25 2.25 0 0 1 4.5 19.5V6.257c0-1.108.806-2.057 1.907-2.185a48.208 48.208 0 0 1 1.927-.184"/></svg></button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="flex items-start gap-4">
|
|
<div class="flex w-7 h-7 shrink-0 items-center justify-center rounded-full bg-brand-primary text-white text-xs font-bold">2</div>
|
|
<div class="min-w-0">
|
|
<p class="text-gray-600 mb-2 leading-7">Remove the WPackagist repository and add WP Packages:</p>
|
|
<div class="flex items-center gap-3 px-4 py-2.5 rounded-xl border border-gray-200/60 bg-gray-100/30 cursor-pointer hover:border-gray-300 transition-colors" onclick="copyCmd(this,'composer config --unset repositories.wpackagist && composer config repositories.wp-packages composer https://repo.wp-packages.org')">
|
|
<span class="text-gray-500 text-sm font-mono select-none shrink-0">$</span>
|
|
<code class="flex-1 text-sm font-mono text-gray-900 truncate">composer config --unset repositories.wpackagist && composer config repositories.wp-packages composer https://repo.wp-packages.org</code>
|
|
<button aria-label="Copy to clipboard" class="shrink-0 text-gray-400 hover:text-gray-900 transition-colors cursor-pointer"><svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M15.666 3.888A2.25 2.25 0 0 0 13.5 2.25h-3c-1.03 0-1.9.693-2.166 1.638m7.332 0c.055.194.084.4.084.612v0a.75.75 0 0 1-.75.75H9.75a.75.75 0 0 1-.75-.75v0c0-.212.03-.418.084-.612m7.332 0c.646.049 1.288.11 1.927.184 1.1.128 1.907 1.077 1.907 2.185V19.5a2.25 2.25 0 0 1-2.25 2.25H6.75A2.25 2.25 0 0 1 4.5 19.5V6.257c0-1.108.806-2.057 1.907-2.185a48.208 48.208 0 0 1 1.927-.184"/></svg></button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="flex items-start gap-4">
|
|
<div class="flex w-7 h-7 shrink-0 items-center justify-center rounded-full bg-brand-primary text-white text-xs font-bold">3</div>
|
|
<div class="min-w-0">
|
|
<p class="text-gray-600 mb-2 leading-7">Require packages with the new naming:</p>
|
|
<div class="flex items-center gap-3 px-4 py-2.5 rounded-xl border border-gray-200/60 bg-gray-100/30 cursor-pointer hover:border-gray-300 transition-colors" onclick="copyCmd(this,'composer require wp-plugin/woocommerce')">
|
|
<span class="text-gray-500 text-sm font-mono select-none shrink-0">$</span>
|
|
<code class="flex-1 text-sm font-mono text-gray-900 truncate">composer require wp-plugin/woocommerce</code>
|
|
<button aria-label="Copy to clipboard" class="shrink-0 text-gray-400 hover:text-gray-900 transition-colors cursor-pointer"><svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M15.666 3.888A2.25 2.25 0 0 0 13.5 2.25h-3c-1.03 0-1.9.693-2.166 1.638m7.332 0c.055.194.084.4.084.612v0a.75.75 0 0 1-.75.75H9.75a.75.75 0 0 1-.75-.75v0c0-.212.03-.418.084-.612m7.332 0c.646.049 1.288.11 1.927.184 1.1.128 1.907 1.077 1.907 2.185V19.5a2.25 2.25 0 0 1-2.25 2.25H6.75A2.25 2.25 0 0 1 4.5 19.5V6.257c0-1.108.806-2.057 1.907-2.185a48.208 48.208 0 0 1 1.927-.184"/></svg></button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</article>
|
|
{{end}}
|