Introducing roboter 1.0

tl;dr: roboter 1.0 is our development style as an npm module. With roboter we highly value code quality and sustainable open source. Version 1.0 has been rewritten from scratch using many insights and learnings of our work on a wide variety of applications.

Although all these applications have different requirements, they also have a lot in common, that we pay attention to. E.g., we put great emphasis on quality assurance in every project. Since we also value automation, in 2015 we started to develop an internal tool to help us to harmonize these common aspects across projects.

Originally this project started as a simple build tool called roboter. In the course of time, however, it has become a way to manifest our development style as code. Since then, we have learned a lot. Based on these insights and learnings, we now rewrote roboter from scratch. The result is roboter 1.0, and we would like to share what's new with you.

Introducing roboter 1.0

The idea in a nutshell

The basic idea of roboter is to be able to install our development style as an npm module. This module provides a set of opinionated tools that automate all regularly recurring tasks of software development in a uniform way. This automation is intended to work for all of our open source modules, but also for private modules.

Of course, however, there are always requirements that differ from project to project and that have to be addressed individually. Although roboter is intended to provide guidelines, it was clear that it has to offer sufficient scope to make individual adjustments if needed and, for example, to integrate custom scripts.

Technical insights

When we started developing roboter, the task runner Grunt was the most obvious basis for automating things in the JavaScript world. Grunt has served us well for quite some time and enabled us to make rapid progress. In fact, roboter was initially just a module for Grunt that simplified writing the configuration file for Grunt.

At some point in time we switched to Gulp, whose configuration is less declarative, and more based on code. Since Gulp heavily relies on streams, this also introduced a significantly better execution speed. Unfortunately, the development of Gulp has stagnated in recent years.

Luckily, many of the basic functions of Gulp, such as evaluating glob patterns, are now also available as npm modules on their own.

While we developed the wolkenkit CLI, we also learned a lot about how to write command line tools and how to use the shell. In the end, this led us to the idea of abandoning Gulp (and any other task runner) completely, and instead to integrate the individual tasks ourselves within the context of our own, much simpler CLI. While doing this we also decided to use less configuration, and more convention.

Testing what you do

For us, writing tests and using test-driven development (TDD) are at the core of our work. This approach allows us to describe assumptions about our code as test cases that can be automatically and rapidly verified at any time. This helps us dramatically to meet new requirements and challenges without risking to damage existing code.

That's why the test task is one of the most important ones to us – and we run it hundreds of times a day. Under the hood, it runs Mocha with some predefined settings. Although many interesting new test runners, e.g. Ava, have entered the scene in the past few years, Mocha still feels like the best approach to us.

With roboter 1.0 we have simplified the creation and usage of different test types, such as unit, integration, or performance tests. Additionally, roboter provides reliable pre and post steps for each individual test type.

Making code look familiar

The consequent use of linting and static code analysis change the way you write code. To us it's the perfect companion to the dynamic type system of JavaScript. That's why we wanted to have a powerful code analysis task in roboter 1.0.

The analyse task runs ESLint under the hood, and by default uses a very, very strict configuration, named eslint-config-es. We use it in our editors while writing code as well as before committing and releasing things.

The fact that we use a very strict configuration is caused by our belief that people shouldn't have to discuss code formatting, instead they should be able to focus on what's really important, i.e. solving their actual problem at hand.

Taking security seriously

In addition to the test and the analyse task there is also the deps task. It checks for missing, outdated, and unused dependencies. On the one hand this helps to keep your project's package.json file clean, on the other hand it notifies you about modules that need to be updated.

We strive to keep our dependencies up-to-date with their latest releases at any point in time, so getting a notification whenever a new version is available for any dependency is pretty important. Additionally, we consider it to be way simpler to regularly introduce minor updates, than to have to update lots of modules once per year – which typically requires resolving many breaking changes.

Putting it all together

All of the tasks we have described so far are meant to assure the quality of your code. This is why you should not only run them often, but also combined: Checking your dependencies' health makes sense once you know that everything is working, and verifying whether things work only makes sense once you know that you don't have syntax errors or similar things in your code.

To make it easy to run these tasks all at once, everytime in the same order, roboter 1.0 provides the qa task. It is nothing but a super task that runs analyse, test and deps in sequential order. Since this is the most important task for your everyday work, it is also run when you don't explicitly run a specific task.

Releasing your code

Once you are fine with your application or module, you typically want to release it as a new version. This is true no matter whether you deal with open source or with private code. Anyway, releasing code often includes a number of steps you need to follow in the right order, such as increasing the version number, creating a tag in Git, pushing the newly created tag, …

This is what the release task of roboter 1.0 is for. It first runs the qa task to ensure that the code you are about to release is actually working, and then runs a number of additional checks and steps. It is also able to generate a TOC in your project's README.md file, and to precompile your code using Babel, if you need to support legacy Node.js runtimes or browsers.

The only thing left to do after having successfully run the release task is to publish the new release to the npm registry – or to whatever registry you are using for your code.

Caring about sustainable open source

We believe that sustainable open source code is what will drive the future of our industry. Among many other things this also means to take open source licenses and other legal stuff more seriously. So, again we have tried to automate the process of identifying legal issues as early as possible.

For that, roboter 1.0 contains the license task that automatically validates the compatibility of the license that you selected with the licenses of any of your dependencies. If there are any uncertainties, roboter warns you about a potential license issue, so that you can care about it before releasing your code into the wild.

As this is so important to get right, the license task is automatically run as part of the previously described release task.

Running npm scripts via roboter

As mentioned in the beginning, many applications and modules have very specific additional tasks that need to be automated. Adding scripts to your package.json file and running them using npm has become the de-facto standard for dealing with this.

So we simply decided to adopt this while providing a standard interface for running the automation tasks. That's why you can run any npm script in the same way as you run the internal tasks of roboter. This way you don't have to remember which script to run using npm, and which to run using roboter – instead you can use roboter for everything.

Installing roboter 1.0

In contrast to the 0.x series of roboter we have decided to avoid using a CLI module that needs to be installed globally. Instead you can now install roboter to your local application context using npm, as you do with any other development dependency:

$ npm install roboter --save-dev

Then, to run roboter you can use npx, which is part of the latest npm releases:

$ npx roboter

If you feel that this is too much typing, you may also create a shell alias and add this to your .profile file (or the respective file of your platform):

alias bot='npx roboter'

Then you can simply run bot instead of npx roboter. Also in contrast to the 0.x series, following a zero configuration approach, there is no more configuration file, such as the previously used roboter.js file.

Conclusion

roboter 1.0 is our development style as an npm module. It helps you to run typical development tasks in an automated way, without the need to configure anything. With roboter we highly value code quality and sustainable open source.

Hence roboter itself is open source, released under the MIT license. Since roboter 1.0 was rewritten from scratch, and introduces a variety of breaking changes compared to the 0.x series, you might want to refer to the upgrading guide if you have used roboter before.

Twitter Facebook LinkedIn

Golo Roden

Founder, CTO, and managing partner

Since we want to deliver elegant yet simple solutions of high quality for complex problems, we care about details with love: things are done when they are done, and we give them the time they need to mature.

Matthias Wagler

Lead core development

Discovering and developing things works better if you're not alone. Hence we pair for everything and always talk about what we think. We are deeply convinced that one and one makes more than just two.