Skip to content

Melange for React Developers

WARNING

This is a work in progress.

We’d love to hear your feedback! If you find any errors or have suggestions for the book, please file an issue or ping @feihong on the #melange channel in the Reason Discord.

What is Melange?

Melange is a collection of tools that bring the robustness of a mature, statically-typed multi-paradigm programming language to the JavaScript ecosystem. That language is OCaml, a language invented in the 1990s which has been battle-tested by industry stalwarts. The heart of Melange is (1) a compiler that translates OCaml to human-readable JavaScript and (2) built-in language constructs for zero-cost interoperation with JavaScript.

Why OCaml?

OCaml codebases scale well both in terms of quantity of lines and number of contributors. The sound type system helps to prevent ambiguous behavior in your program—if it compiles, it runs without runtime errors. OCaml and React (via ReasonReact) are an effective, FP-friendly combination for building frontend UIs using JSX syntax. If the backend is also written in OCaml, you can share types between the frontend and backend, ensuring that they stay in sync[1]. It’s even possible to write universal React components that are rendered on the server with the performance of native code[2].

What’s in this book

This is a project-based, guided introduction to Melange and its ecosystem. Because Melange uses both OCaml and JavaScript ecosystems, there are quite a few tools and concepts to learn. Therefore we try to make each chapter small and digestible, not introducing too many things at once.

Audience

You should already know how to make frontend applications in JavaScript, in particular with React. You should be interested in learning how to leverage your existing knowledge to build apps using ReasonReact. You do not need to know OCaml[3]—we’ll slowly introduce the basics of the language throughout the tutorial. That said, a good complement to this guide is OCaml Programming: Correct + Efficient + Beautiful, which teaches the language from the ground up and goes much deeper into its features.

Chapters and topics

TitleSummaryTopics covered
CounterNumber that can be incremented or decrementedmodule, Option, React.string, pipe last operator, function chaining, switch expression
Numeric TypesUse Melange Playground to explore OCaml’s numeric typesInt, Float, Playground, sharing snippets, comparison operators, arithmetic operators, widgets in Playground
Celsius ConverterSingle input that converts from Celsius to FahrenheitJs.t object, string concatenation (++), exception handling, ternary expression, if-else expression, labeled argument, partial application, {js||js} quoted string literal
Celsius Converter Using OptionThe same component from the last chapter but replacing exception handling with OptionOption, Option.map, when guard
Introduction to DuneA introduction to the Dune build systemdune-project file, dune file, melange.emit stanza, monorepo structure
Order ConfirmationAn order confirmation for a restaurant websitevariant type, primary type of module (t), wildcard (_) in switch, fun syntax, Js.Array functions, React.array, type transformation functions
Styling with CSSStyling the order confirmation using CSSmel.raw extension node, runtime_deps field, glob_files term, external, mel.module attribute
Better SandwichesSupport different kinds of sandwiches by adding constructor argumentsvariant constructor argument, variant pattern matching, {j||j} quoted string literal, Printf.sprintf, building bundles
Better BurgersSupport different toppings for burgers by using recordsrecord type, record destructuring, record pattern matching, submodules, wildcard
Sandwich TestsAdd unit tests for sandwich-related logicopam switch, opam switch, opam install, opam list, .opam file, melange-fest, open module, module_systems field, punning, type inference
Cram TestsSet up cram tests to run your unit testscram tests, cram stanza, Dune alias, promotion, test output sanitization, sandbox, expand_aliases_in_sandbox stanza
Burger DiscountsImplement burger discount logic using arrayslimits of type inference, type annotation of function arguments, full name (asset path), Stdlib, record spread syntax, ignore, runtime representations of common data types, properties of arrays, override Array.get
Discounts Using ListsRe-implement burger discount logic using listsproperties of lists, pattern matching on lists, list spread syntax, List module, ListLabels module, runtime representation of lists, documentation comments, placeholder operator
Promo CodesImplement promo and discount logic using Resultbuilt-in Result type, translating error message to Reason syntax, List.iter, for loops, polymorphic variants, runtime representations of Result and polymorphic variants
Promo ComponentCreate a promo component that renders Results using polymorphic variantDocumentation comment markup language, React.useReducer, as keyword to ignore arguments, opam-check-npm-deps, Result.map, render mutually-exclusive states using polymorphic variant constructors

…and much more to come!


  1. If the backend language isn’t OCaml, you can still share types between frontend and backend through a third-party tool like atd. ↩︎

  2. Note that server-reason-react is not yet polished. However, the parts of its API that are more stable are already used in production by Ahrefs. ↩︎

  3. Because of the focus on ReasonReact, we won’t cover traditional OCaml syntax in this guide. Instead, we’ll cover the Reason syntax which works great with ReasonReact because of its first-class support for JSX. ↩︎