Discussion on CBT: Chris's build tool

You should look into cbt – that’s more or less exactly what it is. Personally, I think it’s a better approach: it may be slightly less powerful, but it’s far easier to understand…



I don’t know cbt, but glancing at the docs, it seems that “slightly less
powerful” is quite an understatement?

As far as I’m concerned, I’m locked into SBT. I’m using Play Framework,
which is an SBT plugin. I’m using IntelliJ IDEA, which has a Scala plugin
that understands SBT projects. Some of my team mates use Eclipse IDE and
the SBT Eclipse plugin. And I’m using SBT Native Packager.

SBT can do build definitions in plain Scala. It’s just not the preferred
way (yet), so that most docs, examples, discussions and so on are (still)
based on the DSL.

 Best, Oliver

Well, it’s very new, only dreamed up a year ago and still very much in development. But the presentation at NE Scala impressed me a lot. It’s rapidly catching up in terms of important everyday capability: the only task I do routinely that clearly wasn’t there yet was Eclipse project export. And since Chris went back to basics and rethought the APIs, I found the build descriptions not just clearer than the sbt DSL, but rather clearer than sbt’s plain-Scala files – it just makes sense. Not to mention that, in some respects, it already works much better than sbt – for example, it keeps things warm in the background with Nailgun, so the load/run cycle is surprisingly fast.

No, it’s not yet ready for me to adopt it in production. But it’s moving rapidly enough, and so far looks good enough, that I’m keeping a close eye on it, and am hoping to be able to make the jump within the next year…


@curoli @jducoeur Hey guys, since it seems you’re having an interesting discussion on cbt, I took the liberty of splitting the conversation into a new thread so that other people involved in the build tool can chime in. /cc @cvogt @ShaneDelmore This way, we don’t go off-topic on the sbt feedback thread :slight_smile: .


@jducoeur @curoli Actually, with the changes that happened over the last year, CBT is now conceptually more powerful than SBT. The model is more expressive if I am not mistaken. And still exactly as simple as it was a year ago. I’ll be speaking about it Thursday at Scala Days. The number of plugins is catching up rapidly, too. Some note worthy gaps right now are indeed IntelliJ, native packager (there is a fat jar plugin however), Eclipse, Play. We’ll likely have a Google Summer of Code student implement IntelliJ support starting in 2 weeks. And I’ll personally take a stab at Play at some point in the next few months.

CBT itself is basically complete. What I’ll be working on over the next months are a few cleanups (some of which will include minor api breakages), writing more docs, implementing more plugins.

I’ll expect a true 1.0 final around summer maybe. But for early adopters it is ready to go right now without running into major road blocks (besides the mentioned plugins). There is a little documentation, but not enough. But the code itself is very simple Scala code and fairly straight forward to follow.

Adding plugins is actually super easy. There are lots of examples, too. And it’s a nice way to learn CBT. hint hint :slight_smile:


I don’t know that I have a lot to say about it. It’s early days, but bring the workflow of working with builds much more in line with your daily “writing plain old scala apps” workflow which is wonderful. Still some rough edges but I am not sure it is going to generate a lot of discussion here because nobody is ever going to need to ask the Scala-Center to create a course teaching people how to use CBT.

Had an interesting discussion with @dwijnand from the sbt team just now. So I was mistaken. CBT is NOT conceptually more powerful than sbt :). CBT just has caught up with a feature that sbt calls commands. These are more powerful than what sbt calls tasks, which was the only thing CBT had before. This power is needed to express things like cross builds, etc.

1 Like

So can they now both express all of the same concepts that the other can? Are they tooling complete?


This might not be the way you want to position cbt relative to sbt, because sbt’s problem is not and never has been a LACK of expressiveness. Its problem is that TOO MUCH is expressible. Especially, there are infinitely many ways to express a setting and have it silently ignored because you didn’t wave the right scope wand over it.

We are drowning in expressiveness in a domain where very little is needed.


It is expressive but also very simple, getting away with much fewer basic building blocks, e.g. no scopes. Try it out again. It’s ready for early adopters at this point :).

Hello Paul (@psp),

Could you be more specific about where you see the problem? Too many
scopes? Or lack of clarity what they mean? Or which ones apply? Or how to
set them? Thanks!

 Best, Oliver

Hello @cvogt,

Could you explain what you use instead of scopes? For example, if I want
a library included for testing only?

 Best, Oliver

In cbt, tests are separate projects or in CBT terminology separate Builds. You can have a multi project build, (which I guess we should probably call multi build) containing both. Your main project’s build has some dependencies. Your test project’s build will need a dependency on your main project, so it can access the code to be tested, but you can add additional dependencies. No scoping needed for that.

In principle, scoping things in CBT means subclassing your build and overriding a method, but only using the subclass selectively when you want that. But the use cases where that is required are vanishing rapidly in CBT.



I didn’t see what you describe here in the CBT docs. Did I miss it?

It’s nice about SBT that you can have a fairly simple setup with a single
project and then use commands like “run”, “test” or “package” in the

I guess CBT shines when you have an unusual setup or when you want to
inject unusual tasks. The question is, how many people need that?

 Best, Oliver

That sounds a lot better. In fact I wonder what scopes accomplish in sbt which couldn’t be achieved with multiple projects.

1 Like

In fact I wonder what scopes accomplish in sbt which couldn’t be achieved with multiple projects.

My understanding so far: nothing. In fact CBT uses something remotely similar to sbt’s projects as the basic building block. The concepts SBT calls “configurations”, “scopes”, “axis”, “multi-project builds”, etc can all be expressed using that one building block. It’s basically a Scala class that contains lazy key value bindings (aka defs), e.g. scalaVersion or compile or classpath. By subclassing them you create different derivations, varying as desired. To not drown in inheritance complexity, CBT keeps the number of defs in the class as small as possible. Plugins usually just add a single key (=def), e.g. def scalariform which returns a case class instance, which can be configured via .copy and has an apply method that actually does what the plugin is supposed to do. If it is supposed to do more than one thing, the case class has several methods, which you can invoke straight from bash you can just call other methods on it than apply, straight from bash. E.g. cbt scalariform.preferences, which then prints your scalariform preferences.

1 Like

I have a feeling the reason it uses configuration scope is to follow Maven’s established convention. But I agree, I too advise using new projects over new configurations because it’s a lot easier to set up correctly.

The only thing holding me back (other than time constraints) on dropping Compile/Test configuration scope is that there are some projects that have 1-to-1 production-to-test code setups. So for them it would double the number of projects they would have – instead of foo, bar, baz, they now have foo, fooTests, bar, barTests, baz, bazTests… :-/

@curoli There currently is only a small tutorial. Most things are not documented including “task scoping”, which is just a pattern in CBT, not a building block. I am planning to write proper documentation in the next few months.

The declared goal of CBT is to shine in both simple and in advanced setups. And I believe it delivers on that.

It’s nice about SBT that you can have a fairly simple setup with a single
project and then use commands like “run”, “test” or “package” in the

You can do the exact same thing with CBT. Just straight from bash. cbt compile, cbt run, cbt test.run. If you don’t like typing cbt every time, we have spun off a separate project to allow custom shells for any program: https://github.com/mchav/with, but I personally prefer the convenience of my ordinary shell, e.g. piping things into unix tools, etc.

The things where CBT starts to shine is on the one hand performance and development turnaround. Try it out, it speaks for itself.

It also shines where sbt projects usually copy and paste or have to deal with the complexities of dependently resolving or compiling things, e.g. for compiler plugins or code-generation. Re-using build code across your projects is very easy with CBT so copy and pasting is not necessary. And downloading or building modules dependently is very easy as well, e.g. for compiler plugins or code-generation.

@olafurpg may have something to add, given how much time he had to invest developing the recent sbt plugins and how quick we were writing the Scala fix plugin at NEScala. sbt is not going anywhere any time soon, but CBT shows how simple things can be. But basically you don’t need to become an expert to make many things happen with CBT and there are not a lot of things to learn in order to become an expert. CBT is made from fairly simple and straight forward Scala code, no monads, no shapeless, no macros.

My work over the next months is focused on further improving the already comparatively friendly learning curve.

I may be blinded by my java years, but I actually like this structure, especially for unit testing. Integration testing warrants a project for itself but I believe that unit tests should be kept as close as possible to the code they are testing.

I would like the (now pretty old) convention of src/main/scala & src/test/scala to be supported by cbt. SBT’s model for this is probably overkill but having the production and test scopes handled by the tool is definitely a huge plus for me.

This is an example of what I said before, where SBT’s design seems to be sought of based off maven, and it makes the tool incredibly confusing because there are so many ways to do one thing.

Maven was also designed with xml in mind, SBT has no such limitation and actual typical SBT builds are very different to how maven does stuff