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

quickwin

v3.2.4

Published

QuickJS Win32 runtime — GUI, networking, WASM, FFI, and more

Readme

English · 中文

QuickWin

Windows 平台上的 QuickJS 运行时,支持原生 GUI、网络、WASM、FFI 等能力。

支持 Windows XP+(32/64 位),保持最小二进制体积(约 1.5MB)。32 位构建已在 QEMU Windows XP 虚拟机中通过 CI 测试。

快速开始

用脚手架新建一个桌面应用(quickwin-starter):

npm create -y quickwin@latest myapp
cd myapp
npm install
npm run build        # 产出 dist\app.exe

默认 React 模板(JSX + 系统托盘),-- --template=minimal 可从更朴素的骨架起步。

特性

  • Win32 原生 GUI —— 原生窗口、按钮、编辑框、列表框、托盘图标、弹出菜单
  • React 渲染器 —— 用 JSX 声明式 GUI,支持 useState/useEffect,diff 增量更新(react-qw)
  • HTTP/HTTPS —— fetch() API、Brotli 解压、chunked 传输、条件缓存
  • WebSocket —— 完整的 RFC 6455 实现,支持 ws:// 与 wss://
  • WebAssembly —— 基于 WAMR,支持标准 WebAssembly.* API
  • FFI —— 内置汇编调用桩,用 bind() 声明式签名调用任意 DLL 函数(无第三方依赖,使用文档)
  • Polyfills —— TextEncoder、URL、URLSearchParams、btoa/atob、crypto.subtle、setTimeout
  • 动态导入 —— import('https://esm.sh/...'),无需安装任何依赖

CLI

运行时本体:npm install quickwin 安装,或从 Releases 下载 qwin.exe 与 main.js。npm 包自带 4 个可执行文件:qwin.exe(64 位)/ qwin-x86.exe(32 位,兼容 XP)及其无 WASM 版本 qwin-nowasm.exe / qwin-nowasm-x86.exe。

npx quickwin node_modules/quickwin/main.js   # 跑包自带的示例
quickwin script.js                  # 运行脚本
quickwin -o CON script.js           # 带控制台运行(AllocConsole)
quickwin -o LOG script.js           # 自动生成日志文件运行
quickwin -e "console.log('hi')"     # 执行表达式
quickwin script.js --flag           # 槽位之后的参数全部传给脚本

选项

| Flag | Description | |------|-------------| | -e <expr> | 执行表达式而不是文件 | | -o CON | 分配控制台(AllocConsole);仅 GUI 子系统构建所需 | | -o LOG | 将 stdout+stderr 重定向到 log_YYYY_MM_DD_HH_MM_SS.txt(exe 所在目录) | | -o <file> | 将 stdout+stderr 重定向到指定文件 | | -d | 开启 HTTP 调试日志 |

命令行按固定槽位解析:exe [-d] [-o 目标] [-e code | 脚本文件];槽位之后的所有参数原样进入 scriptArgs,不报错、不消费。文件槽不接受 - 开头的文件名(用 ./-name.js 运行这类脚本)。

内嵌脚本

可以把一个 JS 脚本直接内嵌进 qwin.exe 二进制 —— 无需重新编译。

格式(追加到 exe 末尾)

[JS bytes (N)] [N: uint32 LE] [magic "QWJS"]

用法

# 内嵌一个脚本
node scripts/embed-js.mjs --exe _build/qwin.exe --js script.js

# 内嵌 Brotli 压缩的脚本(exe 更小,运行时解压)
node scripts/embed-js.mjs --exe _build/qwin.exe --js script.js --compress

# 打包 examples/execd/main.tsx 并 brotli 内嵌进 execd.exe
make execd

# 运行它(不需要文件参数)
_build/execd.exe

不带脚本文件参数运行时,qwin.exe 会检查自身末尾是否有内嵌 JS:找到则执行内嵌代码,否则回退到 main.js。同时支持原始(QWJS)与 Brotli 压缩(QWBR)两种内嵌格式;压缩格式在启动时解压。

模块

| Module | Import | Description | |--------|--------|-------------| | std | built-in | 文件 I/O、环境变量、URL 下载 | | os | built-in | 文件系统、进程、Worker、定时器 | | gui | built-in | Win32 窗口/控件/消息/托盘 API | | sock | built-in | Socket 网络(AddrFamily、FdEvent 等) | | wolfssl | built-in | TLS/SSL(VerifyMode、ReturnCode 等) | | ffi | built-in | 外部函数接口底层(LoadLibrary、GetProcAddress、ffiCall) | | lib/ffi | import './lib/ffi/index.js' | bind() / bindLib() / closure() / struct() 声明式 FFI(使用文档) | | brotli | built-in | Brotli 解压 | | wamr | built-in | 底层 WAMR API | | fetch | import './lib/fetch.js' | 向 globalThis 添加 fetch()、Request/Response/Headers 及其类型声明 | | websocket | import './lib/websocket.js' | 向 globalThis 添加 WebSocket | | polyfill | import './lib/polyfill.js' | 向 globalThis 添加 TextEncoder、URL、btoa/atob、setTimeout | | react-qw | lib/react-qw/ | 面向 Win32 GUI 的 React 自定义渲染器(文档) |

Worker

面向 CPU 密集或 I/O 密集工作创建后台线程。Worker 运行在独立的 QuickJS runtime 中,各自拥有自己的事件循环。

主线程

import * as os from 'os'

const worker = new os.Worker('./worker.js')

worker.onmessage = (e) => {
    console.log('received:', e.data)
    worker.onmessage = null  // 完成后清理
}

worker.postMessage({ type: 'start', value: 42 })

Worker 线程

// worker.js
import * as os from 'os'

const parent = os.Worker.parent

parent.onmessage = (e) => {
    if (e.data.type === 'start') {
        parent.postMessage({ type: 'result', value: e.data.value * 2 })
    } else if (e.data.type === 'done') {
        parent.onmessage = null  // 清理以允许事件循环退出
    }
}

API

| API | Description | |-----|-------------| | new os.Worker(specifier) | 创建 worker。specifier 是文件路径或 URL(支持 https:// 与 data:text/javascript;base64,) | | worker.postMessage(data) | 向 worker 发送消息(JSON 可序列化) | | worker.onmessage = fn | 设置来自 worker 的消息回调。完成后设为 null 以释放消息端口 | | os.Worker.parent | (Worker 侧)父线程的引用 |

清理

通信完成后,双方都必须把 onmessage 设为 null。这会释放消息端口,使事件循环能够干净退出。忘记设置会导致进程挂起。

示例

示例脚本在仓库里(不随 npm 包发布,包内只有 exe、main.js、lib 与类型声明):

.\qwin.exe examples/tray_demo.js     # 系统托盘应用
.\qwin.exe examples/pdf_preview2.js  # 基于 mupdf 的 PDF 阅读器
.\qwin.exe examples/test_tab.js      # 基于 JSX 的标签页 GUI

从源码构建

前置依赖

  • podman(开发容器;构建/测试/QEMU 验证都在容器内完成,与 CI 一致)
  • Git(用于子模块)

构建

git clone --recursive https://github.com/quickwinlabs/quickwin.git
cd quickwin

./docker/dev-podman.sh up      # 启动开发容器(复用 ghcr.io/quickwinlabs/quickwin-dev)
podman exec quickwin-dev bash -lc 'cd /workspace && make js && make cc64 && make test TEST=-net'

make cc64 产出 _build/qwin.exe。cc64-nowasm 会产出更小的 _build/qwin-nowasm.exe,不含 WASM/WAMR(没有 WebAssembly 全局对象); 对这种版本运行 make test TEST=-wasm 跳过 WASM 测试。

构建目标

| Target | Description | |--------|-------------| | make cc64 | 交叉编译 x86_64 → _build/qwin.exe(默认目标,BUILD=fast) | | make cc32 | 交叉编译 i686/XP → _build/qwin-x86.exe | | make cc64-nowasm / cc32-nowasm | 无 WASM/WAMR 版 | | BUILD=fast\|small\|debug | 构建 flavor:make cc64 BUILD=small = -Os+LTO(约 1.5MB,CI 用) | | make js | 通过 tsc 编译 TypeScript | | make wasm | 编译 test/*.wat → WASM fixtures | | make test | 运行全部测试 | | make test TEST=-net | 跳过网络测试(快速) | | make test TEST=wasm | 仅运行 WASM 测试 | | make execd | 打包 examples/execd/main.tsx 并 Brotli 内嵌进 _build/execd.exe | | make npm-pkg | 打包到 dist/quickwin/ | | make gen-const | 重新生成 constants.ts(在 VM 里跑 _build/gen_const.exe) | | make clean / distclean | 清理(会清掉整个 _build/,之后需 make js wasm) |

构建与排错细节见 .agents/skills/workflow/SKILL.md。

许可证

MIT