Docs / BuckleScript / DifferenceFromNativeOcaml

Difference from Native OCaml

This is particularly important when porting an existing OCaml application to JavaScript.

Custom Data Type

In OCaml, the C FFI allows the user to define a custom data type and customize caml_compare, caml_hash behavior, etc. This is not available in our backend (since we have no C FFI).

Physical (in)equality

In general, only use physical equality as an optimization technique; don't rely on its correctness, since it is tightly coupled with the runtime.

String Char Range

Currently, BuckleScript assumes that the char range is 0-255. The user should be careful when they pass a JavaScript string to the OCaml side. We are working on a solution for this problem.

Weak Map

OCaml’s weak map is not available in BuckleScript. The weak pointer is replaced by a strict pointer.


OCaml has int, int32, nativeint and int64 types.

  • Both int32 and int64 in BuckleScript have the exact same semantics as OCaml.

  • int in BuckleScript is the same as int32 while in OCaml it’s platform dependent.

  • nativeint is treated as JavaScript float, except for division. For example, Nativeint.div a b will be translated into a / b | 0.

Note: Nativeint.shift_right_logical x 0 is different from Int32.shift_right_local x 0. The former is literally translated into x >>> 0 (translated into an unsigned int), while the latter is x | 0.


The Printf.print implementation in BuckleScript requires a newline (\n) to trigger the printing. This behavior is not consistent with the buffered behavior of native OCaml. The only potential problem we foresee is that if the program terminates with no newline character, the text will never be printed.

Obj Module

We do our best to mimic the native compiler, but we have no guarantee and there are differences.

Hashtbl Hash Algorithm

BuckleScript uses the same algorithm as native OCaml, but the output is different due to the runtime representation of int/int64/int32 and float.

Marshall Module

Not supported yet.

Str Module

Not supported as it is implemented in C, which is not portable to BuckleScript. Use the Js.String module instead which has bindings to the JavaScript String class.

Sys.argv, Sys.max_array_length, Sys.max_string_length

Command line arguments are always empty. This might be fixed in the future. Sys.max_array_length and Sys.max_string_length will be the same as max_int, but it might be respected.

Unsupported IO Primitives

Because of the JS environment limitation, Pervasives.stdin is not supported but both Pervasives.stdout and Pervasives.stderr are.