package quickjs
All checked builds passInstall
dune-project
Dependency
Authors
Maintainers
Sources
sha256=24e60ef65737c2b8e762b98fbdbc836380425c35c5b3ffae657a14671e51d959
sha512=3868ca89255ebc03ea8a9ba6fe1604c8c5aad5060274d518be99a3300883ebeae864b8b68bf3782875c527a41828f40b3cb75d50179d6802ec0eafd59591af4f
Description
Added to opam-repository:
README
quickjs
quickjs.ml is a set of OCaml bindings to some libraries from QuickJS, a small and embeddable JavaScript engine that aims to support the latest ECMAScript specification.
This project exposes two libraries:
quickjs.c: Low-level OCaml bindings to QuickJS C libs (libregexp,libunicode,js_dtoa,js_atod, andcutils)quickjs: A high-level API that mirrors JavaScript's built-in objects and methods. Modules includeRegExp,String,Number,Global, andUnicode.
Motivation
OCaml can target both native code and JavaScript (via Melange), enabling "universal" code that runs on both platforms. However, JavaScript's specific behavior (such as Unicode, number formatting, and regular expressions) often differs between native OCaml and browser engines. Rather than reimplementing these complex behaviors from scratch, we leverage QuickJS.
This project bridges that gap by bringing the same behavior as JavaScript engines (SpiderMonkey, JavaScriptCore, ChakraCore, v8) into native OCaml. With quickjs.ml, universal code produces identical results whether it runs natively or in the browser.
TC39/test262 Compatibility
We are translating TC39/test262 tests into OCaml to ensure full compatibility with the ECMAScript specification.
Documentation
Usage
Add quickjs library in dune
(libraries quickjs)All string indices (match positions, last_index, String.Prototype methods) are UTF-16 code units, exactly like JavaScript.
open Quickjs
let () =
(* RegExp - JavaScript-compatible regular expressions *)
let re = RegExp.compile ~flags:"g" "(?<word>\\w+)" |> Result.get_ok in
(match RegExp.exec re "hello world" with
| Some m ->
assert (m.captures = [| Some "hello"; Some "hello" |]);
assert (RegExp.group "word" m = Some "hello");
assert (m.index = 0)
| None -> assert false);
(* the global flag advances last_index: the next exec finds "world" *)
(match RegExp.exec re "hello world" with
| Some m -> assert (RegExp.group "word" m = Some "world")
| None -> assert false);
(* Pathological patterns can be bounded with a timeout *)
(try ignore (RegExp.exec ~timeout_ms:100.0 re "hello world")
with RegExp.Timeout -> print_endline "regexp took too long");
(* The 'd' flag records capture group positions (match.indices) *)
let re = RegExp.compile ~flags:"d" "b(c)" |> Result.get_ok in
(match RegExp.exec re "abcd" with
| Some m ->
let indices = Option.get m.indices in
assert (indices.ranges = [| Some (1, 3); Some (2, 3) |])
| None -> assert false);
(* Number.Prototype - JavaScript-identical number formatting *)
assert (Number.Prototype.to_string 0.1 = "0.1");
(* no floating point artifacts *)
assert (Number.Prototype.to_fixed 2 3.14159 = "3.14");
assert (Number.Prototype.to_radix 16 255.0 = "ff");
assert (Number.Prototype.to_exponential 2 123.456 = "1.23e+2");
(* Global - JavaScript global functions *)
assert (Global.parse_float "3.14" = Some 3.14);
assert (Global.parse_int "0x10" = Some 16);
(* Number() literal syntax, with 0x/0b/0o prefixes *)
assert (
Global.parse_float ~options:Global.js_number_options "0xff" = Some 255.0);
(* Number - fast integer to string *)
assert (Number.of_int 42 = "42");
assert (Number.of_int_radix ~radix:16 255 = "ff");
assert (Number.of_int64 9223372036854775807L = "9223372036854775807");
(* String.Prototype - JavaScript string methods *)
assert (String.Prototype.to_lower_case "HELLO" = "hello");
assert (String.Prototype.to_upper_case "world" = "WORLD");
assert (String.from_code_point [| 0x1F600 |] = "😀");
assert (
String.Prototype.split_regex "(x)?(b)" "ab"
= [| Some "a"; None; Some "b"; Some "" |]);
(* Unicode - case folding and the property tables behind \p{...} *)
assert (Unicode.fold_case "Straße" = Unicode.fold_case "STRASSE");
let greek = Option.get (Unicode.script "Greek") in
assert (Unicode.CharSet.mem (Uchar.of_int 0x03B1) greek) (* α *)For more details, see the API reference.
Dev Dependencies (4)
-
ocamlformat
= "0.28.1" & with-dev-setup -
ocaml-lsp-server
with-dev-setup -
odoc
with-doc -
alcotest
with-test
Used by (1)
Conflicts (1)
Build status
Results of building quickjs with each compiler on check.ci.ocaml.org, run of against opam-repository 7cdc698. All results for this package.
Each result links to its build log. To keep crawlers from overloading the site, build logs require a GitHub sign-in (see ocurrent/opam-health-check). On your first log, GitHub asks you to “Authorize opam-health-check”, the OCurrent app that runs these checks; it sees only your public profile, not your repositories. The sign-in lasts 30 days.
| Version | OCaml 4.11 | OCaml 4.14 | OCaml 5.2 | OCaml 5.4 | OCaml 5.5 |
|---|---|---|---|---|---|
| 0.6.0 (this version) | n/a | good | good | good | good |
- good Package successfully built
- partial One of the dependencies failed to build
- bad Package failed to build
- n/a Package is not available in this environment
- internal Internal failure