CINXE.COM
Plugin API
<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"><link rel="apple-touch-icon" sizes="180x180" href="/favicon/apple-touch-icon.png"><link rel="icon" type="image/png" sizes="32x32" href="/favicon/favicon-32x32.png"><link rel="icon" type="image/png" sizes="16x16" href="/favicon/favicon-16x16.png"><link rel="manifest" href="/favicon/site.webmanifest"><title>Plugin API</title><meta name="title" content="Plugin API"><meta name="description" content="The Snowpack Plugin API and how to use it."><meta property="og:type" content="website"><meta property="og:url" content="TODO"><meta property="og:title" content="Plugin API"><meta property="og:description" content="The Snowpack Plugin API and how to use it."><meta property="og:image" content="https://www.snowpack.dev/img/social-2.jpg"><meta property="twitter:card" content="summary_large_image"><meta property="twitter:url" content="TODO"><meta property="twitter:title" content="Plugin API"><meta property="twitter:description" content="The Snowpack Plugin API and how to use it."><meta property="twitter:image" content="https://www.snowpack.dev/img/social-2.jpg"><link rel="stylesheet" href="/_astro/common-1ckxTT.css" type="text/css"><link href="https://fonts.googleapis.com/css2?family=Overpass:wght@400;700;900&display=swap" rel="stylesheet"><style type="text/css"> .layout.astro-Ju9h9Rf8 { display: grid; grid-template-areas: "contents" "main"; grid-gap: 2rem; } @media (min-width: 800px) { .layout.astro-Ju9h9Rf8 { grid-template-areas: "nav contents" "nav main"; } } @media (min-width: 1240px) { .layout.astro-Ju9h9Rf8 { grid-template-areas: "nav main contents"; grid-template-columns: 16rem auto 20rem; } } .layout-nav.astro-Ju9h9Rf8 { grid-area: nav; } @media (min-width: 800px) { .layout-nav.astro-Ju9h9Rf8 { position: sticky; min-height: calc(100vh - 3.5rem); height: calc(100vh - 3.5rem); top: 3.5rem; } } .layout-main.astro-Ju9h9Rf8 { grid-area: main; min-width: 0; padding: 24px 0 24px 0; } @media (min-width: 1240px) { .layout-contents.astro-Ju9h9Rf8 { position: sticky; min-height: calc(100vh - 3.5rem); height: calc(100vh - 3.5rem); top: 3.5rem; } } h3 { position: relative; } .header-link { position: absolute; top: 0; right: 100%; height: 100%; display: flex; align-items: center; font-weight: 400; font-size: 0.75em; padding-left: 0.5rem; padding-right: 0.5rem; color: #c1c1c1; opacity: 0; transition: opacity 100ms linear, color 100ms linear; } .header-link:hover { color: #267dd6; } h3:hover .header-link { opacity: 1; }</style></head><body><nav class="nav astro-ahFEmudE"><button id="toc-drawer-button" class="mobile-open astro-ahFEmudE" type="button" aria-expanded="false" aria-controls="nav-primary"><svg focusable="false" class="hamburger astro-ahFEmudE" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><title>Toggle mobile menu</title><path d="M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z" class="astro-ahFEmudE"></path></svg></button><a class="logo astro-ahFEmudE" href="/"><svg class="logo-icon astro-ahFEmudE" viewBox="0 0 640 512" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><g transform="translate(-1.000000, 0.000000)" fill-rule="nonzero" class="astro-ahFEmudE"><path d="M635.92,462.7 L347.92,14.7 C342.03,5.54 331.89,0 321,0 C310.11,0 299.97,5.54 294.08,14.7 L6.08,462.7 C-0.250773249,472.547007 -0.699487627,485.064987 4.91,495.34 C10.522069,505.612419 21.2945349,512 33,512 L609,512 C620.71,512 631.48,505.61 637.09,495.33 C642.699457,485.058495 642.250708,472.543372 635.92,462.7 Z M321,91.18 L406.39,224 L321,224 L257,288 L218.94,249.94 L321,91.18 Z" id="Shape" class="astro-ahFEmudE"></path></g></svg><span class="logo-type astro-ahFEmudE">Snowpack</span></a><div class="search astro-ahFEmudE"><input type="text" name="search" placeholder="Search documentation..." class="search-input astro-ahFEmudE" id="search-form-input"><span class="search-hint astro-ahFEmudE"><span class="sr-only astro-ahFEmudE">Press </span><kbd class="font-sans astro-ahFEmudE"><abbr title="Command" style="text-decoration: none;" class="astro-ahFEmudE">⌘</abbr></kbd><span class="sr-only astro-ahFEmudE"> and </span><kbd class="font-sans astro-ahFEmudE">K</kbd><span class="sr-only astro-ahFEmudE"> to search</span></span></div><a href="https://github.com/FredKSchott/snowpack/releases" target="_blank" class="link version astro-ahFEmudE">v3.8.8</a><a href="https://github.com/FredKSchott/snowpack" target="_blank" class="link link__desktop astro-ahFEmudE"><svg aria-hidden="true" focusable="false" data-prefix="fab" data-icon="github" class="social astro-ahFEmudE" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z" class="astro-ahFEmudE"></path></svg></a></nav><script> function handleMobileNav(evt) { evt.preventDefault(); /*If hidden-mobile class is enabled that means we are on desktop do overflow normal but we if we are at mobile fixed body position, so that its not scrollable(which currently causing bug) and navbar handling its owns scroll. Case to consider there are chance use can open navbar using toggle button and user when click on any link body postion should be unset */ document.body.classList.toggle('is-nav-open'); const isOpen = document.body.classList.contains('is-nav-open'); if (isOpen) { evt.target.setAttribute('aria-expanded', 'true'); } else { evt.target.setAttribute('aria-expanded', 'false'); } } const mobileNavBtn = document.getElementById('toc-drawer-button'); mobileNavBtn.addEventListener('click', handleMobileNav); mobileNavBtn.addEventListener('touchend', handleMobileNav); if (window.location.pathname.startsWith('/posts')) { mobileNavBtn.style.display = 'none'; } const searchFormInputEl = document.getElementById('search-form-input'); searchFormInputEl.addEventListener('keyup', () => { const gridTocEl = document.querySelector('#nav-primary'); if (searchFormInputEl.value) { gridTocEl.classList.add('is-mobile-hidden'); } else { gridTocEl.classList.remove('is-mobile-hidden'); } }); document.onkeydown = function (e) { if ((e.ctrlKey || e.metaKey) && e.which == 75) { e.preventDefault(); searchFormInputEl.focus(); } }; </script><script type="module" src="/_astro/src/components/docsearch.js"></script><doc-search api-key="562139304880b94536fc53f5d65c5c19" selector="#search-form-input" class="astro-ahFEmudE"></doc-search><div class="wrapper astro-Ju9h9Rf8"><section class="layout astro-Ju9h9Rf8"><aside id="nav-primary" class="layout-nav astro-Ju9h9Rf8"><nav class="nav astro-hk9uDi21"><ol class="contents astro-hk9uDi21"><li class="section astro-hk9uDi21"><span class="header astro-hk9uDi21">Concepts</span><ol class="items astro-hk9uDi21"><li class="astro-hk9uDi21"><a class="link astro-hk9uDi21" href="/concepts/how-snowpack-works">How Snowpack Works</a></li><li class="astro-hk9uDi21"><a class="link astro-hk9uDi21" href="/concepts/dev-server">The Dev Server</a></li><li class="astro-hk9uDi21"><a class="link astro-hk9uDi21" href="/concepts/build-pipeline">The Build Pipeline</a></li><li class="astro-hk9uDi21"><a class="link astro-hk9uDi21" href="/concepts/hot-module-replacement">Fast Refresh & HMR</a></li></ol></li><li class="section astro-hk9uDi21"><span class="header astro-hk9uDi21">Getting Started</span><ol class="items astro-hk9uDi21"><li class="astro-hk9uDi21"><a class="link astro-hk9uDi21" href="/tutorials/quick-start">Quick Start</a></li><li class="astro-hk9uDi21"><a class="link astro-hk9uDi21" href="/tutorials/getting-started">Getting Started</a></li><li class="astro-hk9uDi21"><a class="link astro-hk9uDi21" href="/tutorials/react">React</a></li><li class="astro-hk9uDi21"><a class="link astro-hk9uDi21" href="/tutorials/svelte">Svelte</a></li><li class="astro-hk9uDi21"><a class="link astro-hk9uDi21" href="/tutorials/vue">Vue</a></li></ol></li><li class="section astro-hk9uDi21"><a class="link astro-hk9uDi21" href="/guides"><span class="header astro-hk9uDi21">Guides</span></a></li><li class="section astro-hk9uDi21"><span class="header astro-hk9uDi21">Reference</span><ol class="items astro-hk9uDi21"><li class="astro-hk9uDi21"><a class="link astro-hk9uDi21" href="/reference/configuration">snowpack.config.js</a></li><li class="astro-hk9uDi21"><a class="link astro-hk9uDi21" href="/reference/cli-command-line-interface">Command Line API</a></li><li class="astro-hk9uDi21"><a class="link astro-hk9uDi21" href="/reference/javascript-interface">JavaScript API</a></li><li class="astro-hk9uDi21"><a class="link astro-hk9uDi21" href="/reference/plugins">Plugin API</a></li><li class="astro-hk9uDi21"><a class="link astro-hk9uDi21" href="/reference/environment-variables">Environment Variables</a></li><li class="astro-hk9uDi21"><a class="link astro-hk9uDi21" href="/reference/hot-module-replacement">HMR API</a></li><li class="astro-hk9uDi21"><a class="link astro-hk9uDi21" href="/reference/supported-files">Supported Files</a></li><li class="astro-hk9uDi21"><a class="link astro-hk9uDi21" href="/reference/common-error-details">Common Errors</a></li></ol></li><li class="section astro-hk9uDi21"><a class="link astro-hk9uDi21" href="/plugins"><span class="header astro-hk9uDi21">Plugin Catalog</span></a></li><li class="section astro-hk9uDi21"><a class="link astro-hk9uDi21" href="/news"><span class="header astro-hk9uDi21">Community & News</span></a></li></ol></nav></aside><div class="astro-Ju9h9Rf8"><script type="module" defer="" src="/js/index.js"></script><aside class="subnav astro-6RrcgMjt"><div class="astro-6RrcgMjt"><h4 class="header astro-6RrcgMjt">On this page</h4><nav class="toc astro-6RrcgMjt"><ol class="astro-6RrcgMjt"><li class="astro-6RrcgMjt"><a href="#overview" class="astro-6RrcgMjt">Overview</a></li><li class="astro-6RrcgMjt"><a href="#lifecycle-hooks" class="astro-6RrcgMjt">Lifecycle Hooks</a></li><li class="astro-6RrcgMjt"><a href="#config" class="astro-6RrcgMjt">config()</a></li><li class="astro-6RrcgMjt"><a href="#load" class="astro-6RrcgMjt">load()</a></li><li class="astro-6RrcgMjt"><a href="#transform" class="astro-6RrcgMjt">transform()</a></li><li class="astro-6RrcgMjt"><a href="#run" class="astro-6RrcgMjt">run()</a></li><li class="astro-6RrcgMjt"><a href="#optimize" class="astro-6RrcgMjt">optimize()</a></li><li class="astro-6RrcgMjt"><a href="#onchange" class="astro-6RrcgMjt">onChange()</a></li><li class="astro-6RrcgMjt"><a href="#plugin-properties" class="astro-6RrcgMjt">Plugin Properties</a></li><li class="astro-6RrcgMjt"><a href="#knownentrypoints" class="astro-6RrcgMjt">knownEntrypoints</a></li><li class="astro-6RrcgMjt"><a href="#resolve" class="astro-6RrcgMjt">resolve</a></li><li class="astro-6RrcgMjt"><a href="#plugin-methods" class="astro-6RrcgMjt">Plugin Methods</a></li><li class="astro-6RrcgMjt"><a href="#thismarkchanged" class="astro-6RrcgMjt">this.markChanged()</a></li></ol></nav><hr class="astro-6RrcgMjt"></div><h4 class="header astro-6RrcgMjt">Suggest a change</h4><a href="https://github.com/FredKSchott/snowpack/blob/main/docs" class="astro-6RrcgMjt">Edit this page on GitHub</a></aside></div><article class="layout-main astro-Ju9h9Rf8"><div class="content astro-Ju9h9Rf8"><h2 class="content-title astro-Ju9h9Rf8">Plugin API</h2><div class="content-layout astro-Ju9h9Rf8"><div class="content-body astro-Ju9h9Rf8"><p>Looking to get started writing your own plugin? Check out our <a href="/guides/plugins">Plugin Guide</a> for an overview of how plugins work and a walk-through to help you create your own.</p><p>Looking for a good summary? Check out our <a href="https://github.com/withastro/snowpack/blob/main/snowpack/src/types.ts#L130">“SnowpackPlugin” TypeScript definition</a> for a fully documented and up-to-date overview of the Plugin API and all supported options.</p><h3 id="overview">Overview</h3><pre class=""><code class="language-js"><span class="token comment">// my-first-snowpack-plugin.js</span> module<span class="token punctuation">.</span><span class="token function-variable function">exports</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">snowpackConfig<span class="token punctuation">,</span> pluginOptions</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">{</span> name<span class="token operator">:</span> <span class="token string">'my-first-snowpack-plugin'</span><span class="token punctuation">,</span> <span class="token function">config</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'Success!'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// To use this plugin, add it to your snowpack.config.mjs:</span> <span class="token comment">//</span> <span class="token comment">// export default {</span> <span class="token comment">// plugins: [</span> <span class="token comment">// ["./my-first-snowpack-plugin.js", {/* pluginOptions */ }],</span> <span class="token comment">// ],</span> <span class="token comment">// };</span> </code></pre><p>A <strong>Snowpack Plugin</strong> is an object interface that lets you customize Snowpack’s behavior. Snowpack provides different hooks for your plugin to connect to. For example, you can add a plugin to handle Svelte files, optimize CSS, convert SVGs to React components, run TypeScript during development, and much more.</p><p>Snowpack’s plugin interface is inspired by <a href="https://rollupjs.org/">Rollup</a>. If you’ve ever written a Rollup plugin before, then hopefully these concepts and terms feel familiar.</p><h3 id="lifecycle-hooks">Lifecycle Hooks</h3><h4 id="config">config()</h4><pre class=""><code class="language-js"><span class="token function">config</span><span class="token punctuation">(</span><span class="token parameter">snowpackConfig</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// modify or read from the Snowpack configuration object</span> <span class="token punctuation">}</span> </code></pre><p>Use this hook to read or make changes to the completed Snowpack configuration object. This is currently the recommended way to access the Snowpack configuration, since the one passed to the top-level plugin function is not yet finalized and may be incomplete.</p><h4 id="load">load()</h4><p>Load a file from disk and build it for your application. This is most useful for taking a file type that can’t run in the browser (TypeScript, Sass, Vue, Svelte) and returning JS and/or CSS. It can even be used to load JS/CSS files directly from disk with a build step like Babel or PostCSS.</p><h4 id="transform">transform()</h4><p>Transform a file’s contents. Useful for making changes to all types of build output (JS, CSS, etc.) regardless of how they were originally loaded from disk.</p><h4 id="run">run()</h4><p>Run a CLI command, and connect it’s output into the Snowpack console. Useful for connecting tools like TypeScript.</p><h4 id="optimize">optimize()</h4><p>Snowpack’s bundler plugin API is still experimental and may change in a future release. See our official bundler plugins for an example of using the current interface:</p><ul><li>Example: <a href="https://github.com/withastro/snowpack/tree/main/plugins/plugin-webpack">@snowpack/plugin-webpack</a></li><li>Example: <a href="https://github.com/ParamagicDev/snowpack-plugin-rollup-bundle">snowpack-plugin-rollup-bundle</a></li></ul><h4 id="onchange">onChange()</h4><p>Get notified any time a watched file changes. This can be useful when paired with the <code>markChanged()</code> plugin method, to mark multiple files changed at once.</p><p>See <a href="https://github.com/withastro/snowpack/tree/main/plugins/plugin-sass/plugin.js">@snowpack/plugin-sass</a> for an example of how to use this method.</p><h3 id="plugin-properties">Plugin Properties</h3><h4 id="knownentrypoints">knownEntrypoints</h4><pre class=""><code class="language-html">// Example: Svelte plugin needs to make sure this dependency can be loaded. knownEntrypoints: ["svelte/internal"] </code></pre><p>A list of any npm dependencies that are added as a part of <code>load()</code> or <code>transform()</code> that Snowpack will need to know about. Snowpack analyzes most dependency imports automatically when it scans the source code of a project, but some imports are added as a part of a <code>load()</code> or <code>transform()</code> step, which means that Snowpack would never see them. If your plugin does this, add them here.</p><h4 id="resolve">resolve</h4><pre class=""><code class="language-html">// Example: Sass plugin compiles Sass files to CSS. resolve: {input: [".sass"], output: [".css"]} // Example: Svelte plugin compiles Svelte files to JS & CSS. resolve: {input: [".svelte"], output: [".js", ".css"]} </code></pre><p>If your plugin defines a <code>load()</code> method, Snowpack will need to know what files your plugin is responsible to load and what its output will look like. <strong><code>resolve</code> is needed only if you also define a <code>load()</code> method.</strong></p><ul><li><code>input</code>: An array of file extensions that this plugin will load.</li><li><code>output</code>: The set of all file extensions that this plugin’s <code>load()</code> method will output.</li><li><a href="https://github.com/withastro/snowpack/tree/main/snowpack/src/types/snowpack.ts">Full TypeScript definition</a>.</li></ul><h3 id="plugin-methods">Plugin Methods</h3><h4 id="thismarkchanged">this.markChanged()</h4><pre class=""><code class="language-js"><span class="token comment">// Called inside any plugin hooks</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">markChanged</span><span class="token punctuation">(</span><span class="token string">'/some/file/path.scss'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> </code></pre><p>Manually mark a file as changed, regardless of whether the file changed on disk or not. This can be useful when paired with the <code>markChanged()</code> plugin hook, to mark multiple files changed at once.</p><ul><li>See <a href="https://github.com/withastro/snowpack/tree/main/plugins/plugin-sass/plugin.js">@snowpack/plugin-sass</a> for an example of how to use this method.</li><li><a href="https://github.com/withastro/snowpack/blob/main/snowpack/src/types.ts">Full TypeScript definition</a>.</li></ul></div></div></div></article></section></div><script async="async" src="https://www.googletagmanager.com/gtag/js?id=UA-130280175-9"></script><script> window.dataLayer = window.dataLayer || []; function gtag() { dataLayer.push(arguments); } gtag('js', new Date()); gtag('config', 'UA-130280175-9', { page_path: location.pathname === '/' ? (location.pathname + location.hash) : (location.pathname) }); </script></body></html>