Plinth (formerly known as Plutus Tx) is a subset of Haskell used to write smart contracts for the Cardano blockchain. Plinth code is compiled to Plutus Core, the low-level language the Cardano ledger actually executes on-chain. Because Plinth is a subset of Haskell, it is compiled by GHC.
From a plugin to a compiler
Plinth was previously distributed as a GHC plugin (plutus-tx-plugin): you
used a stock GHC and added the plugin to your project, and during compilation it
intercepted the relevant definitions and translated them to Plutus Core.
plinthc takes a different approach. It is GHC with the Plinth plugin
wired in, producing a single self-contained compiler called plinthc. There is no separate plugin to install or configure: plinthc
behaves like an ordinary GHC, and when a module defines Plinth code it emits the
corresponding Plutus Core alongside the usual outputs.
The plinthc repository holds the build
scripts, the tests and the examples. The compiler sources are two forks, each an
upstream release plus a small set of patches: GHC
(ican-group/ghc-plinth, branch
plinthc-9.12.4 for the recommended GHC 9.12-based compiler, and
plinthc-9.6.7 for the GHC 9.6-based one) and plutus
(ican-group/ghc-plinth-plutus,
branch plinthc-1.70), which supplies plutus-tx, plutus-tx-plugin and
plutus-core.
Why a standalone compiler
Shipping a dedicated compiler, rather than a plugin you add to someone else’s GHC, brings several benefits:
- Simpler setup. Users deal with one tool instead of a GHC plus a matched
plugin package and
-fpluginflags. Pointing cabal atplinthc(see Use plinthc in a project) is all that is needed, and the Plinth machinery stays invisible until a module actually defines Plinth code. - Freedom to adapt GHC. Because the compiler is ours, we can change GHC itself to suit Plinth rather than working within the limits of the plugin interface — better diagnostics, error messages, and developer experience.
- Prebuilt boot libraries with Plinth support. The compiler ships with its boot libraries already built for Plinth, so their definitions compile to Plutus Core out of the box instead of every user rebuilding them.
- Reproducibility. The Plinth-to-Plutus-Core translation is sensitive to how GHC compiles the surrounding code (optimisation passes, inlining, and so on). Pinning the plugin to a specific GHC build keeps compiler and plugin in lockstep, which makes the generated Plutus Core reproducible and lets the whole thing be validated as a single unit (see the test and benchmark scripts in Build plinthc from source).