quickjs.rb
A Ruby wrapper for QuickJS to run JavaScript codes via Ruby with a smaller footprint.
Installation
gem install quickjs
gem 'quickjs'Usage
Quickjs.eval_code: Evaluate JavaScript code instantly
require 'quickjs'
Quickjs.eval_code('const fn = (n, pow) => n ** pow; fn(2,8);') # => 256
Quickjs.eval_code('const fn = (name) => `Hi, ${name}!`; fn("Itadori");') # => "Hi, Itadori!"
Quickjs.eval_code("[1,2,3]") #=> [1, 2, 3]
Quickjs.eval_code("({ a: '1', b: 1 })") #=> { 'a' => '1', 'b' => 1 }Resources
Quickjs.eval_code(code,
memory_limit: 1024 ** 3, # 1GB memory limit
max_stack_size: 1024 ** 2, # 1MB max stack size
)Timeout
# eval_code will be interrupted after 1 sec (default: 100 msec)
Quickjs.eval_code(code, timeout_msec: 1_000)Features
Quickjs.eval_code(code, features: [::Quickjs::MODULE_STD, ::Quickjs::POLYFILL_FILE])| Constant | Description |
|---|---|
MODULE_STD |
QuickJS std module
|
MODULE_OS |
QuickJS os module
|
FEATURE_TIMEOUT |
setTimeout / setInterval managed by CRuby |
POLYFILL_INTL |
Intl API (DateTimeFormat, NumberFormat, PluralRules, Locale) |
POLYFILL_FILE |
W3C File API (Blob and File) |
POLYFILL_ENCODING |
Encoding API (TextEncoder and TextDecoder) |
Quickjs::VM: Maintain a consistent VM/runtime
Accepts the same options as Quickjs.eval_code.
vm = Quickjs::VM.new
vm.eval_code('const a = { b: "c" };')
vm.eval_code('a.b;') #=> "c"
vm.eval_code('a.b = "d";')
vm.eval_code('a.b;') #=> "d"
Quickjs::VM#import: 🔌 Import ESM from a source code
vm = Quickjs::VM.new
# Equivalent to `import { default: aliasedDefault, member: member } from './exports.esm.js';`
vm.import({ default: 'aliasedDefault', member: 'member' }, from: File.read('exports.esm.js'))
vm.eval_code("aliasedDefault()") #=> Exported `default` of the ESM is called
vm.eval_code("member()") #=> Exported `member` of the ESM is called
# import { member, defaultMember } from './exports.esm.js';
vm.import(['member', 'defaultMember'], from: File.read('exports.esm.js'))
# import DefaultExport from './exports.esm.js';
vm.import('DefaultExport', from: File.read('exports.esm.js'))
# import * as all from './exports.esm.js';
vm.import('* as all', from: File.read('exports.esm.js'))
Quickjs::VM#define_function: 💎 Define a global function for JS by Ruby
vm = Quickjs::VM.new
vm.define_function("greetingTo") do |arg1|
['Hello!', arg1].join(' ')
end
vm.eval_code("greetingTo('Rick')") #=> 'Hello! Rick'A Ruby exception raised inside the block is catchable in JS as an Error, and propagates back to Ruby as the original exception type if uncaught in JS.
vm.define_function("fail") { raise IOError, "something went wrong" }
vm.eval_code('try { fail() } catch (e) { e.message }') #=> "something went wrong"
vm.eval_code("fail()") #=> raise IOError transparentlyWith POLYFILL_FILE enabled, a Ruby ::File returned from the block becomes a JS File-compatible proxy. Passing it back to Ruby from JS returns the original ::File object.
vm = Quickjs::VM.new(features: [::Quickjs::POLYFILL_FILE])
vm.define_function(:get_file) { File.open('report.pdf') }
vm.eval_code("get_file().name") #=> "report.pdf"
vm.eval_code("get_file().size") #=> Integer (byte size)
vm.eval_code("await get_file().text()") #=> file content as String
Quickjs::VM#on_log: 📡 Handle console logs in real time
Register a block to be called for each console.(log|info|debug|warn|error) call.
vm = Quickjs::VM.new
vm.on_log { |log| puts "#{log.severity}: #{log.to_s}" }
vm.eval_code('console.log("hello", 42)')
# => prints: info: hello 42
# log.severity #=> :info / :verbose / :warning / :error
# log.to_s #=> space-joined string of all arguments
# log.raw #=> Array of raw Ruby valuesValue Conversion
| JavaScript | Ruby | Note | |
|---|---|---|---|
number (integer / float) |
↔ |
Integer / Float
|
|
string |
↔ | String |
|
true / false
|
↔ |
true / false
|
|
null |
↔ | nil |
|
Array |
↔ | Array |
via JSON |
Object |
↔ | Hash |
via JSON |
undefined |
→ | Quickjs::Value::UNDEFINED |
|
NaN |
→ | Quickjs::Value::NAN |
|
Blob |
→ |
Quickjs::Blob — .size, .type, .content
|
requires POLYFILL_FILE
|
File |
→ |
Quickjs::File — .name, .last_modified + Blob attrs |
requires POLYFILL_FILE
|
File proxy |
← | ::File |
requires POLYFILL_FILE; applies to define_function return values |
License
-
ext/quickjsrb/quickjs -
ext/quickjsrb/vendor/polyfill-intl-en.min.js(bundled and minified frompolyfills/)- MIT License Copyright (c) 2023 FormatJS
- MIT License Copyright (c) 2025 Michael Mclaughlin
Otherwise, the MIT License, Copyright 2024 by Kengo Hamasaki.