Getting started
Installation
miso applications compile to WebAssembly (the primary target) with the GHC WASM backend, or to JavaScript with the GHC JS backend. The quickest way to a working toolchain is the miso flake.
1. Build and serve the sampler
With nix installed (flakes enabled), clone the sampler and run it — the flake provides the whole WASM toolchain (wasm32-wasi-cabal, wasm32-wasi-ghc, http-server, ghciwatch):
$ git clone https://github.com/haskell-miso/miso-sampler && cd miso-sampler
$ nix develop .#wasm --command bash -c 'make all && make serve'
Then open http://localhost:8080. make all runs wasm32-wasi-cabal build, copies static/ to public/, generates the JS FFI glue with post-link.mjs and shrinks the .wasm with wasm-opt. make watch starts ghciwatch with the WASM browser GHCi for hot reload. A JavaScript-backend shell (javascript-unknown-ghcjs-ghc) is available as .#ghcjs, and a plain GHC shell as the default.
2. Wire up your own project
A miso executable is an ordinary cabal executable. For WASM builds it is linked as a reactor and exports hs_start:
executable app
main-is: Main.hs
build-depends: base, miso
if arch(wasm32)
ghc-options:
-no-hs-main
-optl-mexec-model=reactor
"-optl-Wl,--export=hs_start"
cpp-options: -DWASMand Main.hs exports its entry point when compiled for WASM:
{-# LANGUAGE CPP #-}
module Main where
import Miso
#ifdef WASM
foreign export javascript "hs_start" main :: IO ()
#endif
main :: IO ()
main = startApp defaultEvents appThe index.js loader instantiates the module with a WASI shim and calls hs_start. Copy it from the sampler's static/ folder to begin.
Cabal flags
| Flag | Purpose |
|---|---|
ssr | Enable when rendering Views to HTML on a server: text HTML-encodes and hydrateModel is honoured. |
template-haskell | Expose Miso.Lens.TH (makeLenses, makeClassy). |
native | Enable the Lynx native backend (Miso.Native). |
production | Use the minified JavaScript runtime. |