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 🙏

© 2024 – Pkg Stats / Ryan Hefner

@nervive/cyclone

v0.1.0

Published

CLI tool to crush your image

Downloads

1

Readme

@nervive/cyclone

npm

Cyclone is a CLI tool that helps you prepare images during frontend development.

It can compress PNG, JPEG, GIF and SVG lossy and lossless and create AVIF and WebP versions for raster images.

Rationale

As frontend developers we have to care about pictures: compress PNG & JPEG, remove useless parts of SVG, create AVIF and WebP for modern browsers, etc. One day we got tired of using a bunch of apps for that, and created one tool that does everything we want.

Usage

Install the tool:

npm i -g @nervive/cyclone

Optimize!

cyclone path/to/picture.jpg

Command line flags

  • --avif — create AVIF versions for the passed paths instead of compressing them.
  • --webp — create WebP versions for the passed paths instead of compressing them.
  • --force — force create AVIF and WebP even if output file size increased or file already exists.
  • -l, --lossless — optimize losslessly instead of lossily.
  • -v, --verbose — show additional info, e.g. skipped files.
  • -V, --version — show tool version.
  • -h, --help — show help.

Examples

# one image optimization
cyclone path/to/picture.jpg

# list of images optimization losslessly
cyclone --lossless path/to/picture.jpg path/to/another/picture.png

# recursive AVIF creation in the passed directory
cyclone --avif path/to/directory

# recursive WebP creation in the passed directory
cyclone --webp path/to/directory

# recursive JPEG optimization in the current directory
cyclone `find . -type f -name '*.jpg'`

Integrations

External Tool in WebStorm, PhpStorm, etc

Add an External Tool

Open Preferences → Tools → External Tools and add a new tool with these options:

  • Program: path to the exec file (usually simply cyclone)
  • Arguments: desired ones, but use $FilePath$ to pass Cyclone the path of the selected file or directory
  • Working Directory: $ContentRoot$
  • Synchronize files after execution: ✔️

Set other options at your discretion. For example:

As you see on the screenshot above, you may add several “external tools” with the different options passed.

How to use

Run the tool through the context menu on a file or directory:

Shortcuts

To add shortcuts for the added tool go to Preferences → Keymap → External Tools:

Tasks in Visual Studio Code

Add Task

Run >Tasks: Open User Tasks from the Command Palette.

In an open file, add new tasks to the tasks array, for example:

{
  // See https://go.microsoft.com/fwlink/?LinkId=733558
  // for the documentation about the tasks.json format
  "version": "2.0.0",
  "tasks": [
    {
      "label": "cyclone: Optimize Image",
      "type": "shell",
      "command": "cyclone",
      "args": [
        "--verbose",
        {
          "value": "${file}",
          "quoting": "strong"
        }
      ],
      "presentation": {
        "echo": false,
        "showReuseMessage": false,
        "clear": true
      }
    },
    {
      "label": "cyclone: Optimize Image (lossless)",
      "type": "shell",
      "command": "cyclone",
      "args": [
        "--lossless",
        "--verbose",
        {
          "value": "${file}",
          "quoting": "strong"
        }
      ],
      "presentation": {
        "echo": false,
        "showReuseMessage": false,
        "clear": true
      }
    },
    {
      "label": "cyclone: Create WebP",
      "type": "shell",
      "command": "cyclone",
      "args": [
        "--webp",
        "--verbose",
        {
          "value": "${file}",
          "quoting": "strong"
        }
      ],
      "presentation": {
        "echo": false,
        "showReuseMessage": false,
        "clear": true
      }
    },
    {
      "label": "cyclone: Create WebP (lossless)",
      "type": "shell",
      "command": "cyclone",
      "args": [
        "--webp",
        "--lossless",
        "--verbose",
        {
          "value": "${file}",
          "quoting": "strong"
        }
      ],
      "presentation": {
        "echo": false,
        "showReuseMessage": false,
        "clear": true
      }
    }
  ]
}

How to use

  1. Open the file for processing using Cyclone, it should be in the active tab.
  2. Run >Tasks: Run Task from the Command Palette.
  3. Select the required task.

Shortcuts

You can add shortcuts for a specific task by run >Preferences: Open Keyboard Shortcuts (JSON) from the Command Palette.

An example of adding a hotkey to run the "cyclone: Optimize Image (lossless)" task:

// Place your key bindings in this file to override the defaults
[
  {
    "key": "ctrl+l",
    "command": "workbench.action.tasks.runTask",
    "args": "cyclone: Optimize Image (lossless)"
  }
]

Plugin for Sublime Text 3

You’ll find the user settings directory in one of the following paths:

  • macOS: ~/Library/Application Support/Sublime Text 3/Packages/User
  • Linux: ~/.config/sublime-text-3/Packages/User
  • Windows: %APPDATA%\Sublime Text 3\Packages\User

Add plugin

Inside the settings directory create a file cyclone.py with the following content:

import os
import sublime
import sublime_plugin

cyclone = "~/.nodenv/shims/cyclone"

class CycloneCommand(sublime_plugin.WindowCommand):
  def run(self, paths=[], options=""):
    if len(paths) < 1:
      return

    safe_paths = ["\"" + i + "\"" for i in paths]
    shell_cmd = cyclone + " " + options + " " + " ".join(safe_paths)
    cwd = os.path.dirname(paths[0])

    self.window.run_command("exec", {
      "shell_cmd": shell_cmd,
      "working_dir": cwd
    })

Specify path to executable inside cyclone variable, this path can be obtained by running command -v cyclone (on *nix) or where cyclone (on Windows).

Integrate the plugin into the sidebar context menu

Inside the settings directory create a file Side Bar.sublime-menu with the following content:

[
    {
        "caption": "Cyclone",
        "children": [
          {
              "caption": "Optimize Images",
              "command": "cyclone",
              "args": {
                "paths": [],
                "options": "--verbose"
              }
          },
          {
              "caption": "Optimize Images (lossless)",
              "command": "cyclone",
              "args": {
                "paths": [],
                "options": "--lossless --verbose"
              }
          },
          {
              "caption": "Create WebP",
              "command": "cyclone",
              "args": {
                "paths": [],
                "options": "--webp --verbose"
              }
          },
          {
              "caption": "Create WebP (lossless)",
              "command": "cyclone",
              "args": {
                "paths": [],
                "options": "--webp --lossless --verbose"
              }
          }
        ]
    }
]

How to use

Run the tool through the context menu on a file or directory:

Workflow for GitHub Actions

Create cyclone.yml file in the .github/workflows directory of your repository.

Insert the following code into cyclone.yml:

name: cyclone

on:
  # Triggers the workflow on push events but only for the “main” branch
  # and only when there's JPEG/PNG in the commmit
  push:
    branches:
      - main
    paths:
      - "**.jpe?g"
      - "**.png"
  
  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:

jobs:
  convert:
    runs-on: ubuntu-latest

    steps:
      # Install Node.js to avoid EACCESS errors upon install packages
      - uses: actions/setup-node@v2
        with:
          node-version: 14

      - name: Install Cyclone
        run: npm install --global @nervive/cyclone

      - uses: actions/checkout@v2
        with:
          persist-credentials: false # otherwise, the token used is the GITHUB_TOKEN, instead of your personal token
          fetch-depth: 0 # get all commits (only the last one fetched by default)

      - name: Run Cyclone
        run: cyclone --verbose --force --avif --webp .

      - name: Commit changes
        run: |
          git add -A
          git config --local user.email "[email protected]"
          git config --local user.name "github-actions[bot]"
          git diff --quiet && git diff --staged --quiet \
            || git commit -am "Create WebP & AVIF versions"

      - name: Push changes
        uses: ad-m/github-push-action@master
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          branch: ${{ github.ref }}

This workflow will find all JPEG and PNG files in pushed commits and add the AVIF and WebP versions via a new commit.

More examples you can find in the workflows directory.

Troubleshooting

“spawn jpegoptim ENOENT”, “spawn guetzli ENOENT”, etc

Make sure that the ignore-scripts option is not active.

“Cannot find libjpeg”, “pkg-config: command not found”, “fatal error: 'png.h' file not found”, etc

Some operating systems may lack of required libraries and utils, so you need to install them.

Example (on macOS via Homebrew):

brew install pkg-config jpeg libpng