Skip to main content

Provider setup

To begin, create and clone a new repository on GitHub (or another VCS). This repository will be known as your "configuration module" going forward. I suggest naming it dev, dev-configs, or build-tools, etc, as it's straight forward, easy to understand, and defines intent.

git clone<username>/dev.git
cd dev/

Once cloned, initialize a new NPM package, and provide the package name with a username scope, like @beemo/dev. Why a scope? Because we don't want to clutter NPM with common named packages. It also avoids collisions and easily announces ownership.

npm init --scope=<username>

Enter 0.0.0 for the version, and whatever you want for the remaining questions.

Installing Beemo#

Now that we have a repository, we can install and setup Beemo.

yarn add @beemo/core @beemo/cli

This will only install the core functionality. To support different developer tools like Babel, ESLint, and Jest, we need to install packages known as "drivers" (view all available drivers).

yarn add @beemo/driver-babel @babel/core
yarn add @beemo/driver-eslint eslint
yarn add @beemo/driver-jest jest

Drivers and their peer dependencies must be installed as production dependencies.


For each driver you install, there should be an associated configuration file within a configs/ folder, named after the camel-cased package name (excluding "driver-"). Using the example above, we'd have the following:


The benefit of Beemo is that we can avoid different tooling conventions and standardize on a single implementation. No more .foorc, .foorc.js, or .foorc.json nonsense. Just configs/<driver>.ts (and .js too).

Each configuration file should return an object. Easy enough.

import { BabelConfig } from '@beemo/driver-babel';
const config: BabelConfig = {
presets: [
targets: { node: 'current' },
export default config;

You can access the command line args, the pipeline context, and the current tool instance on process.beemo (which allows for runtime conditional logic). For example, if --react was passed, we can enable the React preset.

import { BabelConfig } from '@beemo/driver-babel';
const { context, tool } = process.beemo;
const presets: BabelConfig['presets'] = [
targets: { node: 'current' },
if (context.args.react) {
export default {

Command line arguments are parsed into an object using @boost/args.

Config resolution#

Configuration files are looked for and resolved in the following order:

  • configs/<driver>.ts
  • configs/<driver>.js
  • src/configs/<driver>.ts
  • lib/configs/<driver>.js


Beemo supports executing custom scripts found within your configuration module. To utilize a script, create a file (in PascalCase) within the scripts/ folder, extend the Script class provided by Beemo, and define the execute() and parse() methods.

import { Arguments, ParserOptions, Script, ScriptContext } from '@beemo/core';
interface InitProjectOptions {
dryRun: boolean;
class InitProjectScript extends Script<InitProjectOptions> {
readonly name = 'init-project';
parse(): ParserOptions<InitProjectOptions> {
return {
options: {
dryRun: {
description: 'Execute a dry run',
type: 'boolean',
execute(context: ScriptContext, args: Arguments<InitProjectOptions>) {
if (args.dryRun) {
// Do something
export default () => new InitProjectScript();

The parse() method is optional but can be used to define parsing rules for CLI options (powered by @boost/args). If no rules are provided, default parsing rules will be used.

The execute() method is required and is triggered when the beemo run-script command is ran. This method receives the current pipeline context as the 1st argument and options (parsed with parse()) as the 2nd argument. The Beemo Tool instance is available under this.tool.

Returning a promise in execute() is preferred.

Script resolution#

Script files are looked for and resolved in the following order:

  • scripts/<script>.ts
  • scripts/<script>.js
  • src/scripts/<script>.ts
  • lib/scripts/<script>.js
  • @beemo/script-<script>
  • beemo-script-<script>


Now that Beemo and its drivers are installed, let's move forward by publishing your configuration module to NPM with public access. This is mandatory if using a scope.

npm version minor
npm publish --access=public

You can also set the access in package.json.

"publishConfig": {
"access": "public"