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

@stormcat-works/stormmin

v0.7.1

Published

StormMin: Rust/WASM Lua size optimizer for browser and Node, plus a native-binary CLI with WASM fallback and a demo-UI server

Readme

@stormcat-works/stormmin

StormMin は Stormworks: Build and Rescue の vehicle Lua(マイコンの Lua スクリプト)向けサイズ最適化コンパイラです。プログラム全体を AST・レキシカルバインディング・副作用解析にもとづいて変換し、意味を保存したままゲームの 8192 文字制限に収めやすい Lua を生成します。単なる空白除去・変数リネームのミニファイアではなく、複数の最適化パスと候補探索を組み合わせた最適化コンパイラです。

インストール不要の Web 版はこちら → https://www.makkii.jp/tools/stormworks/stormmin/

β版につき、出力コードにコンパイラ起因のバグが含まれる可能性があります。最適化後のコードは必ずゲーム内で動作確認してください。

このパッケージについて

コンパイラは公開ライブラリStorm Lua EngineのRust実装を使用します。Storm Minは専用CLI/Webと非公開の回帰検証を所有します。このパッケージにはWASM・nativeバイナリ、JavaScriptのloader/Worker/UI、型定義を同梱し、Rustソースや非公開コーパスは含めません。同梱物は次のとおりです。

  • CLI — stormmin コマンド。同梱 native バイナリ(下表)を実行し、対応外プラットフォームでは単一ファイル/JSONプロジェクトのcompileをNode + WASMで実行します(--entry/--modules-dir、lintはnative専用)
  • ブラウザ用ライブラリ — import { compile } で coordinator Web Worker が WASM を遅延ロードし、メインスレッドを塞ぎません
  • Node 用ライブラリ — 同じ import 指定子が Node では in-process WASM 実行に解決されます(出力はブラウザ版と byte 単位で同一)
  • デモ UI — stormmin serve で Web 版と同じ UI をローカル静的配信

| 実行環境 | 要件 | | --------------- | ------------------------------------------------------------------------------------------- | | Node | 20 以上 | | native バイナリ | linux-x64 / win32-x64 / darwin-arm64 / darwin-x64 | | ブラウザ | module Worker が使える現行ブラウザ。SharedArrayBuffer / cross-origin isolation は不要 |

CLI

npm i -g @stormcat-works/stormmin
stormmin input.lua -o output.lua

# インストールせずに1回だけ
npx @stormcat-works/stormmin input.lua -o output.lua
stormmin [compile] [OPTIONS] [FILE]
stormmin compile --entry NAME --modules-dir DIR [OPTIONS]
stormmin compile --project project.json [OPTIONS]
stormmin lint --entry NAME --modules-dir DIR [--format text|json]

FILE 省略時は標準入力(明示する場合は '-'。単一ファイルモードのみ)

compile オプション:
  -o, --output FILE       標準出力の代わりに FILE へ書き出す
      --options JSON      コンパイル/compileProject オプションを JSON で指定
      --options-file FILE 同上を JSON ファイルで指定
      --json              結果全体を JSON で出力(code の代わりに)
      --entry NAME        プロジェクトモード: entry モジュールキー
      --modules-dir DIR   プロジェクトモード: DIR を再帰走査して *.lua をモジュールとして読み込む
      --project FILE      プロジェクトモード: LuaProject 全体を JSON ファイルで指定
      --no-minify         プロジェクトモード: リンクのみ(可読出力 + Source Map)
      --map FILE          最適化後または非短縮のSource Map v3を別ファイルへ書き出す
  -h, --help              ヘルプ
  -V, --version           バージョン

lint オプション:
      --entry NAME / --modules-dir DIR / --project FILE  (compile と同じ)
      --options JSON / --options-file FILE  AnalyzeOptions(例: disabledRules)
      --format text|json  出力形式(既定 text)

Subcommands:
  serve [--port N]        同梱デモ UI をローカル静的配信

例:

# 目標 8192 文字の高速モードで最適化し、結果メタデータも見る
stormmin input.lua --options '{"targetSize":8192}' --json

# property をハードコードして最適化
stormmin input.lua --options '{"property":{"mode":"hardcode","numbers":{"Gain":1.5}}}'

# 複数モジュールをリンク + minify
stormmin compile --entry main --modules-dir src/ -o out.lua

# リンクのみ(可読出力)+ Source Map
stormmin compile --entry main --modules-dir src/ --no-minify --map out.lua.map

# 編集中リント(CI・エディタ統合向けに JSON 出力)
stormmin lint --entry main --modules-dir src/ --format json

--modules-dir は相対パス foo/bar.lua をモジュールキー foo.bar へ変換します(区切りは / のみ)。この対応関係に合わないファイル名(ベース名にドットを含む等)やキー衝突はサイレントスキップせず invalid-module-key 診断として報告します。

ライブラリ API

import { compile } from '@stormcat-works/stormmin';

const result = await compile(source, { mode: 'smallest' });
if (!result.ok) throw new Error(result.error);
console.log(result.code, result.size);

公開 API は次の6つだけです。パス単位の細かい API は公開していません。

  • compile(source, options?) -> Promise<CompileResult> — 単一ソースの最適化本体
  • compileProject(project, options?) -> Promise<ProjectCompileResult> — 複数モジュール(require)+ ambient(sim.* 等)をリンクし、minify オプション既定 true でそのまま最適化まで行う
  • analyze(project, options?) -> Promise<AnalyzeResult> — 解析専用(リンク時と同じ parity 規則 + lint)。構文エラーでも例外を投げず diagnostics に積む。編集中リント向け
  • scanProperties(source) -> Promise<PropertyScanResult> — ソース中の property.get* 読み取りを列挙(hardcode 設定の下準備用)
  • passMetadata() -> Promise<PassMetadataEntry[]> — 表示用パス記録名とIDの対応(全67パスの一覧とは異なる)
  • terminate() — ブラウザのWorkerを破棄。Nodeではno-op

AI Handoff(Web)

Web版の「AIに渡す」は、入力Luaと利用可能な公式ツールをMarkdownまたはJSONへまとめます。設定/Property値と直近のコンパイル結果は個別に含めるか選択できます。docs.makkii.jpの検索MCP https://docs.makkii.jp/mcp、Storm Min CLI/npm API、Storm Lua EngineのSource Map検証APIを明示し、外部AI/Agentが仕様を推測せず機械検証できるようにします。

Storm Min自体には公開HTTP compile APIはありません。HandoffのJSONは kind: "stormmin-ai-handoff" / schemaVersion: 1 です。Source Map本体は自動埋め込みしません。

最適化後Source Map(Engine v0.3.0対応)

Storm Min 0.7.0以降で利用できる機能です。await compile(source, { sourceMap: true, sourceName: "controller.lua" })のcodeとmapを一組で保持します。compileProject(project, { sourceMap: true })にも対応します。CLIはstormmin input.lua -o output.lua --map output.lua.mapです。--map指定時は生成を有効化し、--jsonと併用しても指定ファイルへの保存を省略しません。

mapは標準Source Map v3にEngineのx_storm拡張を含むJSON文字列です。通常のreaderで元位置を参照でき、詳細の検証・解釈はEngineのcompiler SDKが所有します。非短縮project mapは従来どおり返します。mapをLuaに埋め込まず、8192文字制限へ加算しません。

原文全文と固定化された設定を含みます。共有先を確認し、生成Luaを編集した後に古いmapを使用しないでください。 Webでは生成を明示的に有効にし、.luaと.mapを同じbasenameで保存できます。

CompileOptions

| オプション | 型 / 値 | 既定 | 説明 | | ------------------ | -------------------------- | --------------------- | ---------------------------------------------------------------------------------------- | | sourceMap | boolean | false | 最適化後のmapを生成 | | sourceName | string | input.lua | 単一ソースの表示名(空文字/NUL不可)。CLIは入力basenameまたはstdin.luaを使用 | | mode | 'smallest' | 'safe' | smallest | smallest は積極的に最小化。safe はホスト環境の数値演算差などに対して保守的な変換のみ | | property | 下記 | { mode: 'runtime' } | property の扱い | | numericMode | 'tolerant' | 'exact' | tolerant | tolerant は許容誤差内の数値近似を許可。exact は近似・単位リスケール等を無効化 | | numericTolerance | { abs, rel } | 1e-6 / 1e-6 | tolerant 時の絶対・相対許容誤差 | | targetSize | number | なし | 指定すると satisficing search を有効化(後述) | | searchMode | 'exhaustive' | 'fast' | exhaustive | fast は軽量サイズ推定によるビーム探索 | | searchBeamWidth | 1〜16 | 4 | fast 時のビーム幅 | | zeroCostNewlines | boolean | true | 改行を文字数 0 として扱う(Stormworks の制限カウント仕様に合わせる) | | passToggles | Record<string, boolean> | {} | パス個別 ON/OFF。バグ回避用の一時的な逃げ道で、通常運用の調整つまみではない |

property:

  • { mode: 'runtime' } — property.getNumber() / getBool() / getText() 呼び出しを維持(既定)
  • { mode: 'hardcode', numbers: {...}, bools: {...}, texts: {...} } — 指定した property 読み取りだけを literal 化。ローカル変数で property が shadow されている箇所は対象外

targetSize(satisficing search)

targetSize を指定すると、「最短を探し続ける」代わりに「制限を満たすコードをできるだけ早く得る」探索に切り替わります。目標以下の意味保存候補が得られた時点で停止するため大幅に高速です。

const result = await compile(source, { targetSize: 8192 });
console.log(result.size, result.search.targetMet, result.search.stage);
  • 探索は決定的なチェックポイント列(軽量候補 → コスト考慮候補 → full search フォールバック)で、実行時間の計測値を順位付けに使わないため結果は毎回同じです
  • 目標未達でも最良の結果を返し、search.targetMet が false になります
  • targetSize 未指定時は従来どおり最短を探します

CompileResult(主要フィールド)

| フィールド | 説明 | | ----------------------------------------- | --------------------------------------------------------------------------------------------- | | ok | 成功なら true。false のとき error に理由 | | code | 最適化後の Lua ソース | | map | sourceMap:trueで生成した、codeと対になるSource Map JSON文字列 | | original / size / saved | 入力文字数 / 出力文字数 / 削減文字数 | | elapsedMs | 所要時間 | | passes | 適用パスの記録(name / saved / elapsedMs など) | | diagnostics | 診断一覧(Diagnostic[]。下記参照) | | search | 探索統計。targetSize 指定時は targetMet / stoppedEarly / checkpoints / stage を含む | | propertyMode / propertyReadsHardcoded | property の扱いと literal 化した読み取り数 |

Diagnostic(compile / compileProject / analyze 共通)

interface Diagnostic {
  code: string; // 安定な kebab-case 識別子。廃止はあっても意味は変わらない
  severity: 'error' | 'warning' | 'info';
  message: string; // 常に英語固定。UI ローカライズは code をキーにアプリ側で行う
  module?: string; // プロジェクトAPIのみ: 関連モジュールキー
  range?: { line: number; col: number; endLine?: number; endCol?: number }; // 1-based
}

プロジェクトAPI(compileProject / analyze)

複数モジュール(Lua の require)と sim.* のような ambient 名前空間を扱う窓口です。コアはファイルパスを知りません。LuaProject.modules はモジュールキー(. 区切りの Lua 識別子。例: lib.util)→ ソース文字列の map です。

import { compileProject, analyze } from '@stormcat-works/stormmin';

const project = {
  entry: 'main',
  modules: {
    main: 'local util = require("lib.util")\nreturn util.f()\n',
    'lib.util': 'local M = {}\nfunction M.f() return 1 end\nreturn M\n',
  },
};

const linted = await analyze(project); // { ok, diagnostics }
const result = await compileProject(project, { minify: false }); // 可読リンク結果 + Source Map v3
  • compileProject(project, options?)
    • options は CompileOptions を全て含んだ上で minify?: boolean(既定 true)を追加したもの
    • エラー時(require/ambient の規則違反・構文エラー等)は ok:false と diagnostics のみを返す(code/map は返さない)
    • minify:false のときだけ Source Map v3(JSON 文字列)を map に返す
    • usedModules(リンクされたモジュールキー、実行順)・injectedAmbient(注入された ambient メンバー)も返す
  • analyze(project, options?)
    • options.disabledRules で診断コードを個別に抑制できる(severity: 'error' は抑制不可)
    • 構文エラーでも ok:true のまま diagnostics に syntax-error として返す(編集中の呼び出し前提。他モジュールの解析は継続する)
  • require("key") は各モジュールのトップレベル直下の文としてのみ認識されます(式の一部・条件分岐内・動的文字列は全てエラー診断)。詳細な入力スキーマ・require/ambient の制限・診断コード一覧はコアリポジトリの設計ドキュメントを参照してください。

Stormworks 固有制限の検出

Stormworks サンドボックスは標準 Lua の一部しか持たず、input./output. は onTick コールバックの中でしか使えません。analyze() は warning、compileProject() は error(ok:false)としてこれらを検出します(「リンター警告は出るが実行はできる、Minify だけは失敗する」という体験)。

  • sw-unavailable-global: pcall/setmetatable/os/io/coroutine/debug 等、標準 Lua ビルトインとして既知だが Stormworks に存在しないグローバルへの参照(自前で同名グローバルを定義していれば対象外)。error/assert は実機での可否が未確認のため対象外(要確認)。
  • input-outside-ontick / output-outside-ontick: onTick に代入される関数リテラル(function onTick() ... end / onTick = function() ... end)の本体(ネストした内側関数を含む)以外での input./output. 参照。関数呼び出し経由の間接参照は検出しません。

意味保存の保証と決定性

  • 同一入力・同一オプションからは byte 単位で同一の出力を生成します
  • screen.setColor / screen.draw* の観測可能な呼び出し順序を保存します
  • 式の評価回数・評価順・エラー発生位置を変える変換は、安全性を証明できる条件下でしか行いません
  • 変数の同値判定は名前文字列ではなく解決済みバインディング単位で行います。math / screen / input / output / property と同名のローカル変数が定義されているコードでも誤変換しません
  • pack/unpack・ビット演算・テーブル index・numeric-for の境界値に使われる数値は、tolerant モードでも近似しません

性能の目安

入力 20,195 文字の実車両スクリプト、各5回計測の中央値:

| 条件 | Native CLI | ブラウザ (Chrome + WASM) | | ------------------------------------- | ---------: | -----------------------: | | 最短探索(出力 5,248 文字) | 約 2.2 秒 | 約 2.7 秒 | | targetSize: 8192(出力 8,169 文字) | 約 0.6 秒 | 約 0.9 秒 |

既知の制限

  • β版です。最適化は意味保存を目標に設計されていますが、全ての Lua スクリプトでの動作は未保証です。出力は必ずゲーム内で動作確認してください
  • 対象は Stormworks vehicle Lua(onTick / onDraw とマイコン API)です。汎用 Lua ミニファイアとしての利用は想定していません

ライセンス

  • パッケージ本体: MIT License
  • ソースコードは非公開ですが、パッケージに同梱された成果物(WASM / native バイナリ / JS ローダー)は MIT ライセンスで利用・再配布できます。
  • 同梱の Rust モジュールおよび native バイナリで使用しているオープンソースライブラリのライセンス一覧と全文は、パッケージ内の THIRD_PARTY_LICENSES.txt に記載されています(MIT, Apache-2.0, Unicode-3.0 等)。

リンク

  • Web 版(インストール不要・最新版): https://www.makkii.jp/tools/stormworks/stormmin/