はじめに
「アプリにJavaScriptを組み込みたいけれど、V8は大きすぎる…」と感じたことはありませんか?Node.jsやブラウザで使われるV8は強力ですが、バイナリサイズが数十MBに達し、組み込み用途にはヘビー級です。IoTデバイスやプラグインシステム、サンドボックス実行など「小さくJavaScriptを動かしたい」場面では、もっと軽い選択肢が欲しくなります。
そこで登場するのがQuickJSです。FFmpegやQEMUの作者として知られるFabrice Bellard氏が開発した、小型で組み込み可能なJavaScriptエンジンで、Hello Worldプログラムがわずか約367KiBという驚異的なコンパクトさを誇ります。この記事では、QuickJSの特徴からインストール、実践的な活用方法までを解説します。
QuickJSとは
QuickJSは、C言語で書かれた軽量なJavaScriptエンジンです。外部依存が一切なく、数個のCファイルだけで構成されているため、あらゆるCプログラムに簡単に組み込めます。最新版(2026年6月リリース)ではES2025仕様にほぼ完全対応しており、モジュール、非同期ジェネレータ、Proxy、BigIntなどのモダンな機能も利用できます。
主な特徴
- 超軽量 - Hello Worldの実行ファイルが約367KiB。V8やSpiderMonkeyと比べて桁違いに小さく、組み込み機器でも動作します
- 高速起動 - 起動オーバーヘッドがほぼゼロ。ECMAScript公式テストスイート全体を約2分で実行できる処理性能を持ち、最新版は前バージョン比で42%高速化されています
- ES2025対応 - test262(ECMAScript準拠テスト)でほぼ100%のパス率を達成。最新のJavaScript構文がそのまま動きます
- JSを実行ファイルにコンパイル可能 - 付属の
qjscコンパイラで、JavaScriptを依存なしのスタンドアロン実行ファイルに変換できます - 参照カウント方式のGC - メモリ使用量が予測しやすく、省メモリ環境に適しています
- MITライセンス - 商用利用も安心のライセンスです
インストール
ソースからビルド(Linux / macOS)
QuickJSは依存がないため、ビルドも簡単です。
# ソースコードを取得
git clone https://github.com/bellard/quickjs.git
cd quickjs
# ビルドしてインストール
make
sudo make install
これでqjs(インタプリタ)とqjsc(コンパイラ)が使えるようになります。
パッケージマネージャーを使う場合
# macOS (Homebrew)
brew install quickjs
# Ubuntu / Debian
sudo apt install quickjs
Node.jsから使う場合
WebAssembly版のラッパーであるquickjs-emscriptenを使うと、Node.jsやブラウザからQuickJSをサンドボックスとして利用できます。
npm install quickjs-emscripten
基本的な使い方
qjsでスクリプトを実行する
まずは定番のHello Worldです。
// hello.js
console.log("Hello, QuickJS!");
qjs hello.js
# => Hello, QuickJS!
ワンライナーの評価や対話モードも利用できます。
# 式を直接評価
qjs -e "console.log(1 + 2)"
# 対話モード(REPL)
qjs -i
ES Modulesを使う
-mオプション、または拡張子.mjsでESモジュールとして実行できます。
// math.mjs
export function add(a, b) {
return a + b;
}
// main.mjs
import { add } from "./math.mjs";
console.log(add(2, 3)); // => 5
qjs main.mjs
stdモジュールとosモジュール
QuickJSには、ファイルI/Oやシステム操作のためのstd・osモジュールが標準搭載されています。
// file-io.mjs
import * as std from "std";
import * as os from "os";
// ファイルの読み込み
const content = std.loadFile("hello.js");
console.log(content);
// 環境変数の取得
console.log(std.getenv("HOME"));
// ディレクトリの一覧取得
const [files, err] = os.readdir(".");
if (err === 0) {
files.forEach((f) => console.log(f));
}
// タイマーも使えます
os.setTimeout(() => {
console.log("1秒経過しました");
}, 1000);
qjs file-io.mjs
実践的なユースケース
1. qjscでJavaScriptを実行ファイルにする
QuickJS最大の魅力のひとつが、JavaScriptをスタンドアロンの実行ファイルにコンパイルできる点です。Node.jsのインストールされていない環境にも、単一バイナリとして配布できます。
// greet.js
const name = scriptArgs[1] ?? "World";
console.log(`Hello, ${name}!`);
# コンパイル
qjsc -o greet greet.js
# 実行(Node.js不要!)
./greet QuickJS
# => Hello, QuickJS!
-fno-evalや-fno-regexpなどのオプションで不要な言語機能を無効化すれば、バイナリをさらに小さくできます。
2. CアプリケーションにJavaScriptを組み込む
QuickJSの本領は、Cプログラムへの組み込みです。プラグイン機構や設定スクリプトとして、アプリにJavaScriptを実行させられます。
// embed.c
#include "quickjs.h"
#include <stdio.h>
int main(void) {
// ランタイム(ヒープ管理)とコンテキスト(グローバル環境)を作成
JSRuntime *rt = JS_NewRuntime();
JSContext *ctx = JS_NewContext(rt);
const char *script = "const x = 21; x * 2;";
JSValue result = JS_Eval(ctx, script, strlen(script),
"<input>", JS_EVAL_TYPE_GLOBAL);
if (JS_IsException(result)) {
printf("エラーが発生しました\n");
} else {
int32_t value;
JS_ToInt32(ctx, &value, result);
printf("結果: %d\n", value); // => 結果: 42
}
// 後片付け
JS_FreeValue(ctx, result);
JS_FreeContext(ctx);
JS_FreeRuntime(rt);
return 0;
}
gcc embed.c -o embed -lquickjs -lm -lpthread
./embed
JS_NewCFunction()を使えばC関数をJavaScript側に公開でき、双方向の連携も可能です。
3. Node.jsでサンドボックスとして使う
quickjs-emscriptenを使うと、信頼できないコードを隔離された環境で安全に評価できます。ユーザー定義の数式やルールを実行するSaaSなどで便利です。
// sandbox.ts
import { getQuickJS } from "quickjs-emscripten";
async function main() {
const QuickJS = await getQuickJS();
const vm = QuickJS.newContext();
// サンドボックス内で計算式を評価(ホスト環境には一切アクセスできません)
const result = vm.evalCode("[1, 2, 3].map((n) => n ** 2).reduce((a, b) => a + b)");
if (result.error) {
console.error("評価エラー:", vm.dump(result.error));
result.error.dispose();
} else {
console.log("結果:", vm.dump(result.value)); // => 結果: 14
result.value.dispose();
}
vm.dispose();
}
main();
QuickJSのコンテキストはホストのファイルシステムやネットワークから完全に隔離されているため、任意コード実行のリスクを抑えながらユーザースクリプトを動かせます。
まとめ
QuickJSについて、特徴から実践的な使い方までを解説しました。
- 数百KBの超軽量エンジンでES2025にほぼ完全対応
qjsでスクリプト実行、qjscでスタンドアロン実行ファイル化が可能- C APIでアプリへの組み込み、
quickjs-emscriptenでサンドボックス実行も実現
「JavaScriptをもっと身軽に使いたい」あらゆる場面で、QuickJSは頼れる選択肢になります。まずはqjs -iでREPLを触ってみて、そのコンパクトさと起動の速さを体感してみてください。公式ドキュメント(bellard.org/quickjs)には、C APIの詳細やビルドオプションも豊富に載っています。
