npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

vite-plugin-shopify-easel

v0.2.2

Published

Vite plugin for Shopify Liquid themes with HMR, safe asset builds, named bundles, and generated Liquid loaders

Readme

Easel

Easel is an independent Vite plugin and theme generator for Shopify Liquid themes.

It builds JavaScript, TypeScript, and CSS into Shopify theme assets, generates the Liquid that loads them, and safely replaces only output it owns. Shopify CLI remains responsible for authentication, previews, synchronization, and deployment.

Create a theme · Add Easel to a theme · Choosing Easel · Documentation · Examples

Create a new theme

npm create easel-theme@latest my-theme

create-easel-theme scaffolds TypeScript or JavaScript, optional Alpine, React or Vue, and plain CSS or Tailwind CSS. It includes generic Online Store 2.0 JSON templates for the standard storefront page types while leaving current customer accounts to Shopify.

Use . instead of my-theme to scaffold into an empty current directory. Use --yes --no-install for non-interactive automation. Existing files are never overwritten. Generated projects include npm run check:theme for Shopify Theme Check and npm run check:all for source, build, and Liquid validation.

Why Easel

  • Vite-native: use normal Vite plugins, configuration, dynamic imports, HMR, and production builds.
  • Shopify-native: keep the standard Liquid theme structure and use Shopify CLI directly for store operations.
  • Safe publication: stage output, track ownership, reject unsafe overwrites, and roll back interrupted commits.
  • Selective loading: start with one shared entry and add named script, style, or CSS-only bundles when needed.
  • Framework optional: use vanilla TypeScript, Alpine, React, Vue, Tailwind CSS, Sass, or PostCSS through their standard Vite integrations.

Add Easel to an existing theme

pnpm add -D vite-plugin-shopify-easel vite

Easel requires Node.js 22.12 or newer and supports Vite 7 and 8.

From a checkout of this repository, run pnpm install and pnpm create:theme ../my-theme to exercise the local generator. Shopify CLI is installed and authenticated separately.

Start

Keep the Shopify theme at the project root and place source files in src.

assets/
config/
layout/
sections/
snippets/
templates/
src/
  main.ts
  style.css
vite.config.ts

src/main.js also works.

import {defineConfig} from 'vite';
import easel from 'vite-plugin-shopify-easel';

export default defineConfig({
  plugins: [easel()],
});

Render the generated loader inside <head> in layout/theme.liquid.

{% render 'easel-assets' %}

Ignore generated output.

.easel/
assets/easel-*
snippets/easel-assets.liquid

Run Vite and Shopify CLI in separate terminals.

npm run dev
shopify theme dev --notify .easel/shopify-ready

The notification is optional. Vite HMR and Shopify CLI live reload still work without it.

Build before pushing or packaging.

npm run build
shopify theme push

Shopify automatically preloads render-blocking stylesheets in <head> through Link headers, so the generated stylesheet tags don't need preload: true.

Because generated output is ignored by Git, anything that deploys straight from the repository, such as the Shopify GitHub integration, gets no loader or assets. Build in CI and deploy with Shopify CLI, or commit the generated output on the branch Shopify deploys. Run Theme Check after the build, since layouts that render easel-assets report MissingTemplate until it exists.

Named bundles

Load only the code each Liquid surface needs.

import {defineConfig} from 'vite';
import easel from 'vite-plugin-shopify-easel';

export default defineConfig({
  plugins: [
    easel({
      bundles: {
        theme: {script: 'main.ts', style: 'style.css'},
        product: {script: 'product.ts', style: 'product.css'},
        typography: {style: 'typography.css'},
      },
    }),
  ],
});
{% render 'easel-assets', entry: 'product' %}

Bundle paths resolve from src by default. The first bundle is used when entry is omitted.

Configuration

easel({
  // Shopify theme directory relative to the Vite root. Defaults to the Vite root.
  theme: '.',

  // Source directory relative to the Vite root. Defaults to src.
  source: 'src',

  // Named entries relative to source. Defaults to main.ts or main.js with style.css.
  bundles: {
    theme: {script: 'main.ts', style: 'style.css'},
  },

  // Namespace used by generated assets and the Liquid snippet. Defaults to easel.
  namespace: 'easel',

  // Shopify CLI reload coordination. Use false to disable it.
  refresh: {
    // Notification file relative to the Vite root.
    signal: '.easel/shopify-ready',

    // Reload debounce in milliseconds. Defaults to 100.
    delay: 100,
  },
});

Use Tailwind CSS, Alpine.js, React, Vue, Sass, PostCSS, and other tools through their normal Vite setup. React Fast Refresh requires @vitejs/plugin-react/preamble because Easel does not use an HTML entry.

Safe by default

Easel never empties Shopify's shared assets directory. It tracks only its own files, refuses unsafe overwrites, stages builds in isolation, serializes publication, and rolls back interrupted commits.

Production entries keep stable names. Shared chunks, dynamic chunks, imported CSS, images, fonts, and source maps retain Vite's cache safe output behavior.

Shopify CLI remains responsible for authentication, previews, synchronization, pushes, and packaging.

Examples

• examples/vanilla for TypeScript and CSS

• examples/named-bundles for separate product and collection entries

• examples/alpine-tailwind for Alpine.js and Tailwind CSS

• examples/react for React inside Liquid sections

• examples/vue for Vue single file components inside Liquid sections

Each example includes Shopify Theme Editor lifecycle handling and automated build checks.

Support and security

Use the documentation for setup and troubleshooting, open an issue for reproducible bugs and focused feature requests, and use private vulnerability reporting for security concerns. See CONTRIBUTING.md before opening a pull request.

License

MIT