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 🙏

© 2025 – Pkg Stats / Ryan Hefner

esbuild-plugin-scriptable

v0.7.4

Published

An ESBuild plugin for developing Scriptable iOS app scripts with TypeScript, manifest support and auto-deployment

Readme

esbuild-plugin-scriptable

An ESBuild plugin for developing Scriptable iOS app scripts with modern JavaScript tooling.

Requirements

  • Node.js 14 or later
  • esbuild 0.24 or later
  • Scriptable iOS app with iCloud Drive sync enabled

Features

  • Automatically adds Scriptable metadata banner to output files
  • Supports manifest files for script configuration
  • Uses manifest name as output filename (if specified)
  • Handles deployment to iCloud Drive with auto-detection
  • Full TypeScript support with type definitions
  • File filtering with glob pattern matching
  • Custom manifest path mapping
  • Configurable warning behaviors
  • Continues building even when deployment fails (configurable)
  • Detailed deployment logging options

Installation

npm install esbuild-plugin-scriptable --save-dev
pnpm add esbuild-plugin-scriptable --save-dev
yarn add esbuild-plugin-scriptable --dev

Basic Usage

import {build} from 'esbuild';
import {scriptableBanner, scriptableDeploy} from 'esbuild-plugin-scriptable';

await build({
  entryPoints: ['src/widget.ts'],
  outfile: 'dist/widget.js',
  bundle: true,
  plugins: [
    scriptableBanner({
      warnOnMissingManifest: true,
      patterns: '**/*.widget.ts',
    }),
    scriptableDeploy({
      logLevel: 'verbose',
      patterns: '**/*.widget.ts',
    }),
  ],
});

Configuration

Banner Plugin Options

  • manifestExtensions: Custom manifest file extensions (default: ['.manifest.json', '.manifest', '.json'])
  • warnOnMissingManifest: Show warning when manifest file is missing (default: true)
  • warnOnInvalidManifest: Show warning when manifest file is invalid (default: true)
  • warnOnMissingEntry: Show warning when no matching entry point is found (default: true)
  • getManifestPath: Custom manifest file path mapping function
  • patterns: Source file patterns to match entry points (default: ['**/*.{ts,tsx,js,jsx}'])
    • Can be a string or array of strings
    • Supports glob patterns with negation (! prefix)
    • Examples:
      • '**/*.widget.ts' - only process widget source files
      • ['**/*.ts', '!**/*.test.ts'] - exclude test files
  • logLevel: Control logging detail (default: 'auto')
    • 'auto': Use esbuild's logLevel
    • 'silent': No logs
    • 'error': Only errors
    • 'warn': Errors and warnings
    • 'info': Normal output
    • 'verbose': Detailed output

Deploy Plugin Options

  • logLevel: Control deployment logging detail (default: 'normal')
    • 'silent': No logs
    • 'normal': Basic deployment info
    • 'verbose': Detailed deployment info
    • 'debug': All deployment details
  • continueOnError: Continue building when deployment fails (default: true)
  • scriptableDir: Custom Scriptable directory path (default: auto-detect in iCloud Drive)
  • patterns: Source file patterns to match entry points (default: ['**/*.{ts,tsx,js,jsx}'])
    • Can be a string or array of strings
    • Supports glob patterns with negation (! prefix)
    • Examples:
      • '**/*.widget.ts' - only deploy widget source files
      • ['**/*.ts', '!**/*.test.ts'] - exclude test files
  • addBanner: Whether to add Scriptable banner from manifest (default: true)
  • manifestExtensions: Custom manifest file extensions (default: ['.manifest.json', '.manifest', '.json'])

Manifest Configuration

The manifest file can be used to configure both the script metadata and the output filename:

{
  "name": "weather-widget",
  "alwaysRunInApp": true,
  "shareSheetInputs": ["file-url", "url"],
  "iconColor": "blue",
  "iconGlyph": "cloud",
  "version": "1.0.0",
  "description": "A weather widget for Scriptable"
}

When a manifest includes a name property:

  • The deploy plugin will use this name for the output file (e.g., weather-widget.js)
  • If no name is specified, the original filename will be used
  • The banner plugin will still use all manifest properties to generate the script metadata

Advanced Usage

import {build} from 'esbuild';
import {scriptableBanner, scriptableDeploy} from 'esbuild-plugin-scriptable';

await build({
  entryPoints: ['src/widget.ts'],
  outfile: 'dist/widget.js',
  bundle: true,
  plugins: [
    scriptableBanner({
      warnOnMissingManifest: true,
      patterns: ['**/*.ts', '!**/*.test.ts'],
      getManifestPath: entryPath => {
        return entryPath.replace(/\.ts$/, '.manifest.json');
      },
    }),
    scriptableDeploy({
      logLevel: 'verbose',
      addBanner: true,
      patterns: ['**/*.ts', '!**/*.test.ts'],
      scriptableDir: '/custom/path/to/Scriptable',
    }),
  ],
});

Banner Behavior

The banner can be added in two stages:

  1. Build stage (via scriptableBanner plugin):

    • Adds banner to the build output files
    • Banner is part of the compiled result
  2. Deploy stage (via scriptableDeploy plugin's addBanner option):

    • Does not affect build output files
    • Only adds banner to the deployed files in Scriptable directory
    • Will update/override any existing banner in the target file

When using both plugins:

  • scriptableBanner will add banner to build output
  • scriptableDeploy with addBanner: true will update/override the banner in deployed files
  • scriptableDeploy with addBanner: false will keep the existing banner (if any)
// Example 1: Banner in both build output and deployed files
plugins: [
  scriptableBanner({...}),  // Adds banner to build output
  scriptableDeploy({
    addBanner: true   // Updates banner in deployed files
  })
]

// Example 2: Banner only in deployed files
plugins: [
  scriptableDeploy({
    addBanner: true   // Adds banner only to deployed files
  })
]

// Example 3: Banner only in build output
plugins: [
  scriptableBanner({...}),  // Adds banner to build output
  scriptableDeploy({
    addBanner: false  // Keeps existing banner in deployed files
  })
]

The addBanner option in scriptableDeploy:

  • Only affects the files in Scriptable directory
  • Does not modify the build output files
  • When true, will ensure the latest banner from manifest is used in deployed files
  • When false, will preserve any existing banner in the files

License

Apache-2.0