Full-stack web application using purescript (with alternative backend)

Hi, currently my favourite tech stack for programming a web app is based on GHC and GHCJS, provided in the user-friendly all-inclusive framework Obsidiansystems Obelisk.

(Of course, Obsidian doesn’t only provide easy access to the GHC/GHCJS stack, but also includes reflex-platform for functional reactive programming and rightfully advertises itself as “batteries included”, it’s really that user-friendly)

One selling point of this stack is the seamless integration of backend and frontend. Types that are shared between the two are defined in a common module and I thus have type-safety across the server-client-barrier.

Cherry on top: there is servant to define my API (for communication between backend and frontend) and servant-reflex to automagically generate the client-side web requests.


Now my question:

In principle this is possible to have with PureScript, too. I could either rely on node.js for JavaScript in the backend or - even better I guess - I would use purec to compile the backend.

How far is the PureScript ecosystem for this kind of stack?

I don’t insist on a functional-reactive framework like reflex. But what libraries are there ready to be used? Has someone put it all together somewhere already?

These are the libraries I use in Haskell:

  • servant for an API (declaring the API on type-level is nice)
  • servant-reflex for automatically generated web requests
  • servant-server, snap, or some other server framework (I use servant-auth, too, but seems less essential)
  • reflex-dom-core … I guess the best choice for a client-side framework is halogen, but maybe there are others
  • obelisk-route for routing that takes advantage of type-safety

(obelisk does quite a lot of things, I hope I got all the essential stuff)


A PureScript version of the above stack has a chance of outperforming the GHC/GHCJS version, both in computational performance (and memory size, quite important for the client-side code) and in programmer productivity. I happen to like a lot of PureScript design choices a lot.

With obelisk I am stuck at GHC 8.10.7 (which is fine, but not ideal) because of limitations in GHCJS. There is continuous progress on the GHC JavaScript backend that would replace GHCJS, but …

  • I don’t know when this is production ready
  • Haskell to JavaScript still suffers from additional complexity that PureScript avoids.

Thanks for any hints

2 Likes

I found this, but the latest commit is more then 5 years old.

I’m also on the lookout for the most ideal FP full stack solution

I have yet to dig further into Haskell and PureScript though.

Have you considered using such a lib to facilitate the backend-fronted transition? Stack Builders - Connecting a Haskell Backend to a PureScript Frontend

For a “real” full stack solution, there exists a solution resembling OCaml named Eliom: All Ocsigen in one page

It may be worth taking a look. This stack does allow for adhoc mutation but you can constrain yourself to using just monads + FRP. The type system isn’t as sophisticated though.

You have one compiler (and one language) that garanties the 2 worlds are in sync.

I can’t comment on how great it is because I’m still learning OCaml + have yet to study FRP properly first.

Definitely on my radar though.

Note the doc and tooling is a little rough

2 Likes

the first serious application I worked on used Haskell/Servant for the backend and PureScript/Halogen for the frontend. I would say my current stack with GHC/GHCJS is preferable to that.

Both are pretty awesome solutions to write web apps.

It’s just that a full PureScript stack is in reach now … if someone put it all together, it will likely result in a even cleaner solution.


I did forget in my original post the library persistent to handle SQL-style databases. It’s quite powerful and takes care of migrations, too. As far as I understand, databases in the PureScript world are handled by means of rather thin wrappers.

1 Like

I’ve written some full-stack PureScript projects just for personal stuff, so not really at scale. (Our frontend at my workplace is PureScript, so I’ve done frontend at scale, just not full-stack). I use HTTPure on node-js with routing-duplex, and that all works really great for full-stack. I believe HTTPurple as an alternative to HTTPure has a bunch of momentum, but I don’t have any experience with it. The biggest sticking point for me was having to FFI for all the database stuff, because there really aren’t many backend database libs for PureScript for NodeJS. But I do draw some comfort in having all of the NodeJS ecosystem just an FFI away, since FFI is pretty easy in PureScript.
At work we use react-basic-hooks for our frontend, but on my personal projects I wanted to play around with concur, since it has such an interesting take on UI. I’m not familiar enough with the Haskell ecosystem to comment on direct replacements of the libraries you use.

With some embarassment, I will share the project link GitHub - ntwilson/recipes: Track recipes and build grocery lists.
but the readme is completely misleading (I migrated from Heroku + PostgresDB to Azure + CosmosDB when Heroku got rid of their free tier and didn’t update the readme at all) and I make no claims about the state of the code.

3 Likes

great thank you for these insights

I will look up those frameworks/packages.

This is potentially a disadvantage. I have to admit, though, that the fairly advanced haskell library persistent isn’t a perfect solution, either. It’s a complex beast. I am used to it and it works for me, but I understand why people tend to write this stuff application specific.

concur originates in haskell land … will definitely look into that.

For Node.js stuff:

  • Bindings to Node’s http2 module were only recently added this year, but no libraries AFAIK are actually using them yet.
  • httpurple uses Node’s http/https modules to implement a web server and is likely what you want. I think it’s the most mature out of other options right now and includes the type-safe routing via routing-duplex. The Registry currently uses this library. At some point, I wanted to update this library to use http2 and expose those internals, but I haven’t gotten around to it yet.
  • hyper was the PureScript version of servant, but I don’t know whether it’s been updated recently.
  • selda is a library for constructing type-safe SQL queries over PostGres/SQLite databases but I’m not sure whether it’s been updated recently. I personally didn’t like the usage of typeclass-based codecs to serialize values from/to the database, but due to the type-level machinery, it was hard to convert that to value-based ones. But if you’re already using a servant-like API, that’s likely not an issue for you?
  • node-execa is a library that wraps Node’s child_process module in case you needed to execute some CLI programs in your server
  • Things you’ll likely need FFI for:
    • template libraries for building an HTML string that contains a mixture of dynamic and static content. AFAIK, we don’t currently have such a library.
    • image manipulation programs (if needed)
5 Likes

I’m also considering purescript on the backend because of lack of an up-to-date database driver in haskell and other “batteries” in the haskell eco system are sometimes not up to par. Purescript can use JS, i don’t mind writing bindings. Also purescript-bridge to convert the types is not as powerful as you ideally want it to be. Being able to share types and other codes directly seems very attractive.

Does someone know if the following will work and has a full featured solution for it?

  • Websockets
  • Authentication

Any more perspectives and user stories on purescript backend very welcome!

If you’re willing to write the FFI, everything works!