PureScript: a Haskell-inspired language that compiles to JavaScript
A strongly-typed language that compiles to JavaScript
At a glance
- What is it?
- PureScript is a small, strongly typed language written in Haskell and compiled to JavaScript. It suits programmers who want expressive types and purity in a JavaScript runtime, and it asks them to accept a separate toolchain and a smaller package index.
- Who is it for?
- Adopt PureScript if your team already reads Haskell-style types and needs to ship JavaScript without giving up purity; skip it if you want a single npm-based toolchain or a package index the size of npm. Before committing, verify that the latest release line matches the compiler version your chosen libraries target, since the release notes list v0.15.17-0 and v0.15.16 as separate tags, and check the compiler's own INSTALL.md for the supported build path on your platform.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 85 days ago.
- What is it written in?
- Mainly Haskell, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem PureScript solves for JavaScript teams
JavaScript runs everywhere, and that is the only reason most teams use it. Its type system is optional and its functions are impure by default, so a value can change under you between two calls, and a missing case in a match is a runtime error rather than a compile error. PureScript takes the opposite position: it is a small, strongly typed language with expressive types that compiles to JavaScript, written in and inspired by Haskell. The output is JavaScript, so it runs in a browser, in Node.js, or anywhere else the runtime exists.
The audience is narrow and identifiable. You are a developer who wants algebraic data types, type classes and row polymorphism, but you cannot move the runtime off JavaScript because the browser is the deployment target or the existing libraries are npm packages. PureScript is not a superset of JavaScript and it does not try to be. It is a separate language with its own compiler, its own package index (Pursuit) and its own module system. If you want to keep writing JavaScript and add types on top, this is the wrong tool, and the related search phrase "purescript vs typescript" captures exactly that fork.
How the compiler, modules and FFI fit together
The repository is a compiler written in Haskell. The top-level layout shows src/ for the compiler source, app/ for the executable entry point, tests/ for the test suite, and psc-ide/ for editor integration. The build is driven by stack.yaml and purescript.cabal, with a Makefile wrapping the common commands. That structure tells you what PureScript is at this level: a Haskell program whose job is to read .purs modules and emit JavaScript.
A PureScript program is a set of modules, each declaring the types and values it exports. Types are checked at compile time across module boundaries, and the compiler emits JavaScript per module. When you need to call existing JavaScript, you write a foreign function interface declaration in PureScript and supply the implementation in a separate JavaScript file. That boundary is where the guarantees stop: the compiler trusts the JavaScript side of the FFI, so a wrong type annotation there produces a wrong program that still compiles. Row polymorphism is the mechanism behind records that carry a known set of fields plus whatever else the caller added, which is how PureScript models things like component props without falling back to an index signature.
The compiler is distributed as an executable named purs. The repository also contains bundle/ and npm-package/, which is how the compiler is packaged for distribution outside the Haskell toolchain.
Installing the compiler and compiling a first module
The README points to the project home, the releases page and the documentation repository rather than giving a single install command, and INSTALL.md exists at the top level for build instructions. What the repository does show is the Makefile target used to install the executables through Stack. The Makefile defines it as stack install, which places the purs executable on Stack's binary path. This is the build-from-source route. If you do not want to build a Haskell project, the npm-package/ directory and the bundle/ directory are the packaging paths the maintainers use to ship the compiler to users who do not have a Haskell toolchain.
Once purs is on your path, the compiler is invoked over source files. The Makefile's run target shows the pattern the maintainers use for the executable itself:
stack exec -- pursTo compile a module, pass the source file to the compiler. The tests/ directory holds the compiler's test inputs, and the Makefile's test target is the entry point the repository documents for running them:
stack test --fast purescriptA PureScript source file is a module whose name matches the file name, and the compiler reports the modules it compiled and writes the generated JavaScript to disk. If a module fails to type check, the compiler prints the error against the source location instead of emitting output. The generated JavaScript is ordinary JavaScript, which is the point: you can load it from Node.js or a browser bundle.
Where PureScript gets in your way
The first cost is the toolchain. The compiler is a Haskell program built with Stack or Cabal, and the Makefile's help target lists build, build-dirty, run, install, ghci, test and ghcid, all of which assume a working Haskell environment. A team that only knows npm now has to keep a GHC toolchain alive in CI, or depend on the packaged compiler and accept whatever version that packaging ships. Neither path is wrong, but both are more moving parts than installing a JavaScript transpiler.
The second cost is the FFI boundary described earlier. Purity is enforced inside PureScript modules; it is not enforced across the boundary into JavaScript. Every npm package you call is an untyped region, and the type you write for it is a claim the compiler cannot check. The third cost is ecosystem size. Pursuit is the package index, and it is not npm. Libraries exist for common work, and the related searches show people reaching for purescript halogen and purescript react, but the long tail of small utilities you would install from npm in a JavaScript project often has no PureScript equivalent.
Finally, the documentation does not describe a rollback story for the compiler itself. INSTALL.md covers getting the compiler onto a machine; the README does not document downgrading a project to an earlier compiler release. If your build depends on a specific compiler version, that is a constraint you manage yourself.
PureScript against TypeScript, Elm, Haskell, ReScript and Gleam
The related searches around this project are almost all comparisons, which is a fair signal about how people encounter it. TypeScript is the closest practical alternative and the difference is philosophical before it is technical. TypeScript adds a structural type system on top of JavaScript, so existing JavaScript is already valid input and the type annotations are erased. PureScript is a different language with nominal and row-based types, and its output is generated rather than annotated. If you need to adopt types incrementally in an existing codebase, TypeScript is the only one of the two that lets you do that.
Elm is the other obvious comparison. Elm is a language that compiles to JavaScript with a strong emphasis on a single architecture for user interfaces, and it is deliberately narrower than PureScript, which has type classes and a general-purpose foreign function interface. Haskell is the language PureScript is written in and inspired by, but Haskell compiles to native code and has a much larger runtime and library ecosystem; PureScript keeps the type-level ideas and drops the runtime. ReScript and Gleam are also typed languages targeting JavaScript or a BEAM runtime, and both make different trade-offs around how much of the host language they expose. ClojureScript goes the other direction entirely, keeping a dynamic Lisp and relying on runtime data structures rather than a static type checker.
Maintenance, releases and what the licence file leaves open
The repository is not archived, and the last push was on 2026-07-08. Recent releases include v0.15.17-0 on 2026-06-07 and v0.15.16 on 2026-03-15, with an earlier v0.15.16-8 tag from 2025-10-18. The versioning policy is a tracked file, VERSIONING_POLICY.md, and there is a RELEASE_GUIDE.md plus a CHANGELOG.md and a CHANGELOG.d/ directory for pending entries. That combination suggests releases are cut deliberately rather than continuously, and the presence of a versioning policy document is the thing to read before you decide how tightly to pin the compiler.
The licence field for this repository is reported as NOASSERTION, which means the automated classifier could not map the LICENSE file to a known identifier. The repository does contain a LICENSE file and a license-generator/ directory. Do not treat the NOASSERTION label as a statement about the terms; read the LICENSE file itself, and if you are redistributing the compiler or bundling it into a product, get that checked rather than inferred.
Who should pick up PureScript and who should not
Pick it up if you already think in Haskell-style types, you want those types to reach a JavaScript runtime, and you are willing to run a second toolchain alongside npm. The compiler, the test suite and the editor integration all live in this repository, so the surface you have to learn is finite and visible. The PureScript book and the documentation repository are the entry points the README lists, and Try PureScript exists for evaluating the language without installing anything.
Do not pick it up if your team's constraint is that everything installs from npm, or if your project is mostly a thin layer over a large set of existing JavaScript libraries. The FFI boundary means those libraries arrive untyped, and you will spend your time writing type claims the compiler cannot verify. Do not pick it up either if you need incremental adoption inside an existing JavaScript codebase; that is TypeScript's problem to solve, not this one.
The first thing to verify is version alignment. Check which compiler release your chosen libraries target before you pin anything, because the release list shows both a v0.15.17-0 line and a v0.15.16 line, and a library compiled against one will not necessarily work with the other.
Editorial conclusion
Adopt PureScript if your team already reads Haskell-style types and needs to ship JavaScript without giving up purity; skip it if you want a single npm-based toolchain or a package index the size of npm. Before committing, verify that the latest release line matches the compiler version your chosen libraries target, since the release notes list v0.15.17-0 and v0.15.16 as separate tags, and check the compiler's own INSTALL.md for the supported build path on your platform.
Frequently asked questions
What is PureScript?
It is a small strongly typed programming language with expressive types that compiles to JavaScript, written in and inspired by Haskell. The compiler itself is a Haskell program in this repository, and the executable it produces is named purs.
What is PureScript used for?
It is used to write programs that run on a JavaScript runtime while keeping static types and purity inside PureScript modules. The README lists a book, a documentation repository and a package index called Pursuit as the resources for learning and building with it.
What are the key differences between TypeScript and PureScript?
TypeScript annotates JavaScript and erases those annotations, so existing JavaScript is valid input. PureScript is a separate language with its own compiler, module system and package index, and it generates JavaScript rather than annotating it, which means it cannot be adopted incrementally inside a JavaScript codebase.
Is PureScript dead?
The repository is not archived and the last push was on 2026-07-08, with releases v0.15.17-0 on 2026-06-07 and v0.15.16 on 2026-03-15. The project also keeps a CHANGELOG.d/ directory for pending changelog entries, which is where unreleased work is recorded.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/purescript-purescript)