ReasonML with Phoenix?

This just means that brunch cannot find the npm files, don’t think this is a bucklescript/reason issue at all. Are you able to import other npm files via an ES6 javascript file directly? That’d definitely be the first thing I’d test.

I suppose it is possible that if BuckleScript is globally installed Brunch may not be able to find the packages.

Maybe npm link bs-platform etc.? If Brunch follows links …

Absolutely do not use globally installed packages with brunch. In fact never use globally installed bucklescript at all as it’s API has a tendency to break from version to version and thus a project that ‘was’ working suddenly does not work. You should put all NPM dependencies for a project (including bucklescript) as a devDependency in the packages.json file for NPM. Anyone that says that bucklescript can safely be installed globally (including the author, I really don’t know where he gets the idea that this is safe, as you can plainly see with such an issue) should be ignored.

This is one of the reasons that I’m leaning back to the, though more unreadable output, but actually and properly consistent js_of_ocaml over bucklescript. The gain in readability from bucklescript is not worth the breakages it keeps doing, especially it’s DSEL attributes it keeps adding all over the place.

Better yet I want webassembly to become in higher use now, that is the end-game way to go, and bucklescript won’t work there as it is, but js_of_ocaml (via normal ocaml) will.

So one basically has to assume that people will install it globally.

bs-platform is installed as a dev dependency and is present in node_modules. I also tried just now to use lodash because I saw it in there as well and that works without issue just after an import. Just to re-iterate: It loads bs-webapi that then tries to import bs-platform but fails, so I don’t think that the node_modules availability is really the issue here.

This issue looks similar

and unfortunately wasn’t resolved.

I have no idea how Brunch works internally … but lodash being strictly a library would be listed under dependencies. bs-platform being a transpiler, a tool is under devDependencies - but it also contributes libraries that are technically dependencies. Now in terms of npm package organization this may be a valid thing to do - but I have to wonder whether that structure is violating some assumptions that Brunch is making internally (technically one would assume that any library under node_modules that is imported somewhere would be bundled, as it would to seem to be more work to constrain it to packages that are listed under dependencies).

The differences between dependencies and devDependencies is that devDependencies are available to everything at non-server-running time, and dependencies are available at all times, regardless of a nodejs server running or not. Since the nodejs server is not used as a server with Phoenix then it doesn’t matter, it works with brunch regardless. :slight_smile:

I’m using an older bucklescript version at work though since they keep doing questionable things later, but it definitely works here, and I did use it with brunch at one point, but currently it is just passed to rollup for packing (which works so much better than brunch, pass the files to rollup then to babel).

Are you able to import one of the bs javascript files into a javascript module too?

1 Like

I’m unable to import both bs-webapi and bs-platform even though I can use both of these in the build process with bsb and they’re both present in the node_modules directory.

Funnily enough I saw on the discord server that this issue with modules not being available actually was solved (by some people) by linking to a global install of bucklescript instead of having it in the node_modules directory. Just to see if that was the case now I tried it as well, but to no avail.

1 Like

Hmm, maybe compare the pathing to ones that do work and see what differs?

Out of curiosity I tried using bs-fetch as a dependency to see if this was a general issue with using bs dependencies and it works without issue. As soon as I use anything from bs-webapi I get that error on page load.

I’ve been in the same issue today while trying to use BuckleScript for the first time in a Phoenix + Brunch project. Adding a require("bs-platform/lib/js/curry.js"); in a JavaScript file bundled by Brunch works as a workaround. Though this is quite strange because ElementRe.js is bundled and contains exactly:

var Curry = require("bs-platform/lib/js/curry.js");

Does it work correctly with Webpack? I haven’t yet set up a working environment with it, but since Phoenix is migrating to it I consider using Webpack myself for new projects.

That particular issue had it’s continuation in this topic:

i.e. a similar issue cropped up with Rollup.

If I remember correctly it boiled down to (incorrect) mixing of JS module formats.

Rollup is ESM oriented, while Brunch needs CJS - so you have tweak the Bucklescript transpilation configuration accordingly.

In Rollup’s case, it was bothered by the transpiled (CJS-version) of phoenix.js and much happier with the non-transpiled ESM-version of phoenix.js.

So it wouldn’t surprise me one bit if success with webpack depends largely on getting the various output JS module formats all correctly lined up.

1 Like

Webpack is the only one that works out of the box, yes. Using it to bundle only the BuckleScript apps is what we do right now and there have been no issues whatsoever. Ideally we’d skip brunch alltogether but messing with something that works in the scope of JS is just inviting needless issues.

Here are some config files (some names changed because this is contract code):

const path = require('path');

module.exports = {
  mode: "production",
  entry: {
    "app_one": "./bucklescript/",
    "two": "./bucklescript/",
    "three": "./bucklescript/",
    "example-app": "./bucklescript/"
  output: {
    path: path.resolve(__dirname, "..", "priv", "static", "js"),
    filename: "[name]-bs.js"

This means that our packaged apps will show up alongside our brunch bundles as <app-name>-bs.js and that’s how we’d refer to them in pages.


  "name": "project-name",
  "sources": { "dir": "bucklescript" },
  "generate-merlin": true,
  "bs-dependencies": [
  "package-specs": {
    "module": "commonjs",
    "in-source": true
  "suffix": ".bs.js",
  "bsc-flags": [
    "-bs-super-errors -no-alias-deps",
    "-w @8"


  watchers: [
    node: [
      cd: Path.expand("../assets", __DIR__)
    sh: [
      cd: Path.expand("../assets", __DIR__)
    node: [
      cd: Path.expand("../assets", __DIR__)

Note that if you use an earlier version of bsb it wasn’t suitable for using as a watcher so you’d have to run a script that took care of closing when STDIO closed, etc. The delayed webpack script is just a script that waits a bit for bsb to compile everything and then does packaging because it was easier than figuring out if there is a way to have webpack not complain about the entry points not being there.

For docker I’ve made a version of the build that precompiles the bucklescript compiler and never pulls it from npm and the bs toolchain compilation is cached, so making changes to the code really only means having the rest of the npm stuff taking time, not the super dumb “Oh, you don’t have an OCaml compiler, ninja and bsb? We’ll build all three” thing that happens. The only way I managed to get the behavior I wanted was by using yarn link to get the behavior I thought npm link should’ve been (npm overwrites links if you do npm install). This way you can get a set bsb version that works within the whole JS build flow for a cost you pay only when you change something foundational in your Dockerfile:

RUN apk update && apk --update upgrade && apk add [a bunch of stuff] opam parallel m4 yarn

RUN opam init && opam update && opam switch 4.02.3+buckle-1 && opam install cppo

RUN git clone bs \
    && cd bs && git checkout 3.1.5

RUN cd bs && eval $(opam config env) \
    && yarn install \
    && cd vendor/ocaml \
    && ./configure -prefix `pwd` && make world.opt && make install \
    && cd ../.. && make && make install && yarn link


RUN parallel "sh -c" ::: "mix local.rebar --force" "mix local.hex --force" && \
    eval $(opam config env) && \
    mix deps.get --only prod && \
    parallel "sh -c" ::: "MIX_ENV=prod mix compile" \
    "cd 'apps/project_name/assets' && npm install --global brunch && yarn link bs-platform && yarn install --production --prefer-offline && bsb -make-world && node_modules/.bin/webpack && brunch build --production"

There are probably hundreds of ways to get this behavior and they might well be simpler than this one. This one is what I found after messing around with it, though.


ive been using reason for 2 months and i kinda like it, well until i ran into a problem, the community.
is there a recommended way to use ocaml to compile to reactjs or something similar that i can use to go to native, the whole reason for using reason it its supposed to allow to native compilation thereby alievating me from having to dig into kotlin, my project makes extensive use of websockets, which was a pain in reason to which i documented and submitted a pr. however the response to the simpelist of issues i ask on their discord channel has made me never want to deal with their community again, im looking for a better solution and one with a community of mature adults that are willing actually help noobs onboard rather than alienate them while they silo their knoweledge and look down their noses at ye stoopid plebs.

I’ve generally seen the reason community be pretty nice, but they are definitely on the younger side. The OCaml community tends to be more mature, very much like the erlang community. I think elixir and reason mirror each other a big like how erlang and ocaml communities do. ^.^;

But yeah, to use OCaml just use bucklescript straight out (it has a fantastic build system that wraps all the ocaml old horror-tools). Or if you don’t need as much javascript foreign calls and/or want to compile some source-less ocaml code then JSOO (java-script-of-ocaml) is the way to go (but you gotta use the old ocaml tools then). :slight_smile:

/me is always a fan of freely giving all knowledge

1 Like

A fresh boilerplate with phoenix 1.4!



The funny thing is when I first came to Elixir I was surprised at how experienced everyone was - part of the reason I started the forum actually was to get more people like me (non-experts!) into Elixir :slight_smile: But yeah, on the whole I think we’ve got a good mix here now - and particularly over the last couple of years we’ve attracted many more newcomers to Elixir and some to programming in general as well.

I can’t speak for communities like OCaml, but I guess they are simply not attracting the same number of people other languages are - hence the people in their communities seem to be getting older with time, with fewer young people entering. Again I cannot speak for other communities but I would not always correlate maturity with age - I have seen (and hosted!) communities predominantly aimed at older people and they have been far from what we might consider mature.

In terms of community spirit though @mithereal, I think you will be hard pressed to find a more happy and helpful community than in Elixir :003:

1 Like

Ya the elixir forums are awesome, but then again so is elixir. lots of that has to do with how good the support and docs are erlangs docs i find are harder to parse through than elixirs, therefore i didnt use it nearly as much as i use elixir. I think Reasons are a bear as concepts arent fleshed out but i wanted that ios and android app that the docs promised lol. I wonder what age group is mostly on here in terms of programming years.


2 posts were split to a new topic: What questions can we ask for our 2019 bump of our polls?

After a lot of suffering with webpack, I moved to parcel, and succesfuly added SASS :slight_smile:
so it’s a REASON-PARCEL-SASS-PHOENIX 1.4 boilerplate !