1.0.0 (released on 17 Jun 2016)

Scala.meta is a clean-room implementation of a metaprogramming toolkit for Scala, designed to be simple, robust and portable. We are striving for scala.meta to become a successor of scala.reflect, the current de facto standard in the Scala ecosystem.

Scala.meta provides functionality that's unprecedented in the Scala ecosystem. Our killer feature is abstract syntax trees that capture the code exactly as it is written - with all the original formatting and attention to minor syntactic details.

With scala.meta, we are building a community of next-generation tooling for Scala. Codacy's Scala engine and Scalafmt take advantage of our unique features and deliver user experiences that have been unreachable for the most of the traditional Scala tools.

Getting started

To get started with scala.meta, add the following to your build.sbt:

libraryDependencies += "org.scalameta" %% "scalameta" % "1.0.0"

Next, you'll need to add a single wildcard import to the files where you'll be using scala.meta. Unlike with scala.reflect, the metaprogramming library from the standard distribution, no complicated setup is necessary.

import scala.meta._


High-fidelity parsing. Note how the abstract syntax trees in the printout below contain comprehensive information about formatting and comments. This is an exclusive feature of scala.meta.

scala> "x + y /* adds x and y */".parse[Term]
res0: scala.meta.parsers.Parsed[scala.meta.Term] = x + y /* adds x and y */

scala> "List[ Int ]".parse[Type]
res1: scala.meta.parsers.Parsed[scala.meta.Type] = List[ Int ]

Tokens. Scala.meta takes even the finest details of Scala code into account. We achieve this by attaching tokens, data structures representing atomic units of Scala syntax, to our abstract syntax trees. Note that the abstract syntax tree in the printout doesn't have the comment per se - it is stored in tokens instead.

scala> val tree = "x + y /* adds x and y */".parse[Term].get
tree: scala.meta.Term = x + y /* adds x and y */

scala> tree.syntax
res0: String = x + y /* adds x and y */

scala> tree.structure
res1: String = Term.ApplyInfix(Term.Name("x"), Term.Name("+"), Nil, Seq(Term.Name("y")))

scala> tree.tokens.structure
res2: String = Tokens(BOF [0..0), x [0..1),   [1..2), + [2..3),   [3..4), y [4..5),   [5..6), /* adds x and y */ [6..24), EOF [24..24))

Dialects. Scala.meta is designed from the ground up to be platform-independent. This means that we understand different versions of the base language: Scala 2.10, Scala 2.11 and even Dotty. We also support Sbt build files to make sure we cover as much Scala code as possible.

scala> import scala.meta.dialects.Sbt0137
import scala.meta.dialects.Sbt0137

scala> Sbt0137("""
  lazy val root = (project in file(".")).
  settings(name := "hello")
res0: scala.meta.parsers.Parsed[scala.meta.Source] =

  lazy val root = (project in file(".")).
  settings(name := "hello")

Quasiquotes. Scala.reflect is notorious for being obscure and user-unfriendly, but it has its moments. Quasiquotes have proven to be an amazing productivity booster, so we implemented them in scala.meta, and now they are better than ever. Note how the precise types for x and y prevent the programmer from generating invalid code. Learn more about quasiquotes in our documentation.

scala> val addition = q"x + y"
addition: meta.Term.ApplyInfix = x + y

scala> val q"$x + $y" = addition
x: scala.meta.Term = x
y: meta.Term.Arg = y

scala> q"$y + $x"
<console>:13: error: type mismatch when unquoting;
 found   : scala.meta.Term.Arg
 required: scala.meta.Term
              q"$y + $x"


Semantic API. Our first priority is to come up with an API that will provide functionality to perform typechecking, name resolution, implicit inference, etc. It is crucial to fully model the language and achieve feature parity with scala.reflect.

New-style ("inline") macros. As announced at ScalaDays NYC 2016, macros based on scala.reflect are going to be dropped from the future versions of Scala. We are now working on the replacement, so-called inline macros, under the banner of Macro Paradise 3.0. You may be interested in visiting to check out the state of the art.

Other execution environments. The current version of scala.meta can only be run with Scala 2.11. This means that it is very hard or outright impossible to write scala.meta-based tools targetting Scala 2.10 (e.g. running in sbt 0.13.x) or Scala.js. Vote for #295 and #359 on our issue tracker if that's important for you.


Metaprogramming 2.0 (ScalaDays New York City / Berlin 2016). These talks explain the status of scala.meta, demonstrate key features, cover the early adopters and publish our plans for the future. Of special interest is the extensive story of what's going to happen to macros and live demos of new-style ("inline") macros.

The talk in Berlin happened a month after the talk in New York City. It features a clearer explanation of how new-style macros are going to work and adds live demos of IntelliJ integration for new-style macros, Codacy and Scalafmt. At the moment, the video of Berlin's talk is not available, but slides also provide a lot of information.

Video from New York City (May 2016):
Slides from Berlin (Jun 2016):



(c) 2014 - 2016 scala.meta contributors
Fork me on GitHub