{"id":13508234,"url":"https://github.com/valderman/haste-compiler","last_synced_at":"2025-05-15T07:05:55.643Z","repository":{"id":2313148,"uuid":"3272927","full_name":"valderman/haste-compiler","owner":"valderman","description":"A GHC-based Haskell to JavaScript compiler","archived":false,"fork":false,"pushed_at":"2019-03-17T10:49:58.000Z","size":4176,"stargazers_count":1443,"open_issues_count":63,"forks_count":111,"subscribers_count":55,"default_branch":"master","last_synced_at":"2025-04-14T12:58:41.412Z","etag":null,"topics":["compiler","ghc","haskell","javascript","language","web"],"latest_commit_sha":null,"homepage":"http://haste-lang.org","language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/valderman.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2012-01-26T10:23:30.000Z","updated_at":"2025-04-09T18:38:49.000Z","dependencies_parsed_at":"2022-09-05T14:50:10.633Z","dependency_job_id":null,"html_url":"https://github.com/valderman/haste-compiler","commit_stats":null,"previous_names":[],"tags_count":36,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/valderman%2Fhaste-compiler","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/valderman%2Fhaste-compiler/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/valderman%2Fhaste-compiler/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/valderman%2Fhaste-compiler/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/valderman","download_url":"https://codeload.github.com/valderman/haste-compiler/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254292042,"owners_count":22046426,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["compiler","ghc","haskell","javascript","language","web"],"created_at":"2024-08-01T02:00:50.166Z","updated_at":"2025-05-15T07:05:50.631Z","avatar_url":"https://github.com/valderman.png","language":"Haskell","funding_links":[],"categories":["Haskell"],"sub_categories":[],"readme":"Haste\n=====\n[![Build Status](https://travis-ci.org/valderman/haste-compiler.svg?branch=master)](https://travis-ci.org/valderman/haste-compiler.svg?branch=master)\n\nA compiler to generate JavaScript code from Haskell.\n\nIt even has a [website](http://haste-lang.org) and a\n[mailing list](https://groups.google.com/d/forum/haste-compiler).\n\nFeatures\n--------\n\n* Seamless, type-safe single program framework for client-server communication\n* Support for modern web technologies such as WebSockets, WebStorage and Canvas\n* Simple JavaScript interoperability\n* Generates small, fast programs\n* Supports all GHC extensions except Template Haskell\n* Uses standard Haskell libraries\n* Cabal integration\n* Simple, one-step build; no need for error prone Rube Goldberg machines of\n  Vagrant, VirtualBox, GHC sources and other black magic\n* Concurrency and MVars with Haste.Concurrent\n* Unboxed arrays, ByteArrays, StableNames and other low level features\n* Low-level DOM base library\n* Easy integration with Google's Closure compiler\n* Works on Windows, GNU/Linux and Mac OS X\n\n\nInstallation\n------------\n\nYou have three options for getting Haste: installing from Hackage, from\nGithub or from one of the pre-built\n[binary packages](http://haste-lang.org/#downloads).\nIn the first two cases, you need to add add Cabal's bin directory, usually\n`~/.cabal/bin`, to your `$PATH` if you haven't already done so.\nWhen installing from the Mac, portable Windows or generic Linux package,\nyou may want to add `path/to/haste-compiler/bin` to your `$PATH`.\nThe Debian package as well as the Windows installer and the optional\ninstall script included in the generic Linux package\ntake care of this automatically.\n\nOr, you can install the latest stable version from Hackage:\n\n    $ cabal install haste-compiler\n    $ haste-boot\n\nBuilding from Github source is equally easy. After checking out the source,\n`cd` to the source tree and run:\n\n    $ cabal install\n    $ haste-boot --force --local\n\nAlternatively, you may also build from Github source using Stack:\n\n    $ stack install\n    $ haste-boot --force --local\n\nSee `doc/building.md` for more information about build requirements and\nprocedures for the various platforms.\n\nIf you are having problems with the `haste-cabal` installed by `haste-boot`,\nyou can try building it from scratch and then passing the `--no-haste-cabal`\nflag to `haste-boot`:\n\n    $ git clone https://github.com/valderman/cabal.git\n    $ cd cabal \u0026\u0026 git checkout haste-cabal\n    $ cd Cabal \u0026\u0026 cabal install\n    $ cd ../cabal-install \u0026\u0026 cabal install\n\nWhen installing Haste from GitHub, you should probably run the test suite first,\nto verify that everything is working. To do that, execute\n`./runtests.sh` in the Haste root directory.  You may also run only a particular\ntest by executing `./runtests.sh NameOfTest`.  The test suite uses the `nodejs`\ninterpreter by default, but this may be modified by setting the `JS` environment\nvariable as such: `JS=other-js-interpreter ./runtests.sh`. Other JavaScript\ninterpreters may or may not work. `runtests.sh` isn’t downloaded when installing\nfrom Hackage. You would have to download it from GitHub.\n\nTo build the patched Closure compiler used when compiling using `--opt-minify`,\nget the Closure source, apply `patches/closure-argument-removal.patch` and\nbuild it as you normally would. This is not usually necessary however,\nas `haste-boot` fetches a pre-compiled Closure binary when run.\n\nFor more detailed build instructions, see `doc/building.md`.\n\nHaste has been tested to work on Windows and OSX platforms, but is primarily\ndeveloped on GNU/Linux. As such, running on a GNU/Linux platform will likely\nget you less bugs.\n\n\nUsage\n-----\n\nTo compile your Haskell program to a JavaScript blob ready to be included in an\nHTML document or run using a command line interpreter:\n\n    $ hastec myprog.hs\n\nThis is equivalent to calling ghc --make myprog.hs; Main.main will be called\nas soon as the JS blob has finished loading.\n\nYou can pass the same flags to hastec as you'd normally pass to GHC:\n\n    $ hastec -O2 -fglasgow-exts myprog.hs\n\nHaste also has its own set of command line arguments. Invoke it with `--help`\nto read more about them. In particular `--opt-all`, `--opt-minify`,\n`--start` and `--with-js` should be fairly interesting.\n\nIf you want your package to compile with both Haste and, say, GHC, you might\nwant to use the CPP extension for conditional compilation. Haste defines the\npreprocessor symbol `__HASTE__` in all modules it compiles. This symbol may\nalso be used to differentiate between Haste versions, since it is defined\nas an integer representation of the current Haste version. Its format is\n`MAJOR*10 000 + MINOR*100 + MICRO`. Version 1.2.3 would thus be represented as\n10203, and 0.4.3 as 403.\n\nHaste also comes with wrappers for cabal and ghc-pkg, named haste-cabal and\nhaste-pkg respectively. You can use them to install packages just as you would\nwith vanilla GHC and cabal:\n\n    $ haste-cabal install mtl\n\nFinally, you can interact with JavaScript code using the `Haste.Foreign`\nmodule in the bundled `haste-lib` library.\nSee `doc/js-externals.txt` for more information about that.\nThis library also contains all sorts of functionality for DOM manipulation,\nevent handling, preemptive multitasking, canvas graphics, native JS\nstring manipulation, etc.\n\nFor more information on how Haste works, see\n[the Haste Report](http://haste-lang.org/hastereport.pdf \"Haste Report\"),\nthough beware that parts of Haste may have changed quite a bit.\n\nYou should also have a look at the documentation and/or source code for\n`haste-lib`, which resides in the `libraries/haste-lib` directory, and the\nsmall programs in the `examples` directory, to get started.\n\n\nInterfacing with JavaScript\n---------------------------\n\nWhen writing programs you will probably want to use some native JavaScript\nin your program; bindings to native libraries, for instance.\nThe preferred way of doing this is the `Haste.Foreign` module:\n\n    {-# LANGUAGE OverloadedStrings #-}\n    import Haste.Foreign\n    \n    addTwo :: Int -\u003e Int -\u003e IO Int\n    addTwo = ffi \"(function(x, y) {return x + y;})\"\n\nThe `ffi` function is a little bit safer than the GHC FFI in that it enforces\nsome type invariants on values returned from JS, and is more convenient.\nPerformance-wise, it is roughly as fast as the GHC FFI except for complex types\n(lists, records, etc.) where it is an order of magnitude faster.\n\nIf you do not feel comfortable throwing out your entire legacy JavaScript\ncode base, you can export selected functions from your Haste program and call\nthem from JavaScript:\n\nfun.hs:\n\n    {-# LANGUAGE OverloadedStrings #-}\n    import Haste.Foreign\n    import Haste.Prim (toJSStr)\n\n    fun :: Int -\u003e String -\u003e IO String\n    fun n s = return $ \"The number is \" ++ show n ++ \" and the string is \" ++ s\n\n    main = do\n      export \"fun\" fun\n\nlegacy.js:\n\n    function mymain() {\n      console.log(Haste.fun(42, \"hello\"));\n    }\n\n...then compile with:\n\n    $ hastec '--start=$HASTE_MAIN(); mymain();' --with-js=legacy.js fun.hs\n\n`fun.hs` will export the function `fun` when its `main` function is run.\nOur JavaScript obviously needs to run after that, so we create our \"real\" main\nfunction in `legacy.js`. Finally, we tell the compiler to start the program by\nfirst executing Haste's `main` function (the `$HASTE_MAIN` gets replaced by\nwhatever name the compiler chooses for the Haste `main`) and then executing\nour own `mymain`.\n\nThe mechanics of `Haste.Foreign` are described in detail in this\n[paper](http://haste-lang.org/ifl15.pdf).\n\n\nEffortless type-safe client-server communication\n------------------------------------------------\n\nUsing the framework from the `Haste.App` module hierarchy, you can easily write\nweb applications that communicate with a server without having to write a\nsingle line of AJAX/WebSockets/whatever. Best of all: it's completely type\nsafe.\n\nIn essence, you write your web application as a single program - no more forced\nseparation of your client and server code. You then compile your program once\nusing Haste and once using GHC, and the two compilers will magically generate\nclient and server code respectively.\n\nYou will need to have the same libraries installed with both Haste and vanilla\nGHC (unless you use conditional compilation to get around this).\n`haste-compiler` comes bundled with all of `haste-lib`, so you\nonly need to concern yourself with this if you're using third party libraries.\nYou will also need a web server, to serve your HTML and JS files; the binary\ngenerated by the native compilation pass only communicates with the client part\nusing WebSockets and does not serve any files on its own.\n\nExamples of Haste.App in action is available in `examples/haste-app` and\n`examples/chatbox`.\n\nFor more information about how exactly this works, see this\n[paper](http://haste-lang.org/haskell14.pdf).\n\n\nBase library and documentation\n------------------------------\n\nYou can build your own set of docs for haste-lib by running\n`cabal haddock` in the Haste base directory as with any other package.\n\nOr you could just look at\n[the online docs](http://haste-lang.org/docs/).\n\n\nLibraries\n---------\n\nHaste is able to use standard Haskell libraries. However, some primitive\noperations are still not implemented which means that any code making use\nof them will give you a compiler warning, then die at runtime with an angry\nerror. Some libraries also depend on external C code - if you wish to use such\na library, you will need to port the C bits to JavaScript yourself (perhaps\nusing Emscripten) and link them into your program using `--with-js`.\n\n\nKnown issues\n------------\n\n* Not all GHC primops are implemented; if you encounter an unimplemented\n  primop, please report it together with a small test case that demonstrates\n  the problem.\n\n* Template Haskell is still broken.\n\n* Generated code is not compatible with the vanilla Closure compiler's\n  `ADVANCED_OPTIMIZATIONS`, as it is not guaranteed to preserve\n  `Function.length`.\n  `haste-boot` bundles a compatibility patched version of Closure which does\n  preserve this property. Invoking `hastec` with the `--opt-minify` option\n  will use this patched version to minify the generated code with advanced\n  optimizations.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvalderman%2Fhaste-compiler","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvalderman%2Fhaste-compiler","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvalderman%2Fhaste-compiler/lists"}