Skip to content
A toolkit for building JavaScript & Typescript applications.
JavaScript HTML
Branch: master
Clone or download
connor-baer feat(plop): add option to use custom templates (#59)
* feat(plop): add option to use custom templates

* docs(plop): document templateDir option

* feat(plop): add option to customize the template extension
Latest commit 5ba08fa Nov 29, 2019
Type Name Latest commit message Commit time
Failed to load latest commit information.
.circleci docs: Prepare Foundry for OSS (#49) Jun 28, 2019
.gitignore feat: Add support for semantic-release (#35) May 17, 2019
.releaserc.js docs: Prepare Foundry for OSS (#49) Jun 28, 2019
package.json fix(deps): use local configs to avoid false positives for vulnerabili… Nov 25, 2019
yarn.lock fix(deps): use local configs to avoid false positives for vulnerabili… Nov 25, 2019

Build status Code coverage npm version License Contributor Covenant


An opinionated but configurable CLI (Command Line Interface) toolkit for writing JavaScript. We currently support React, Node, and vanilla JavaScript with varying feature breadth.


  1. Set up desired configuration files, npx foundry bootstrap-config —eslint —prettier.

  2. Add commands to package.json

    "scripts": {
        "lint": "foundry run eslint src"
  3. Be productive and don’t worry about tooling dependencies.

Table of contents


Foundry is supposed to be installed as a dev-dependency (development) via the npm or Yarn package managers. The npm CLI ships with Node. You can read how to install the Yarn CLI in their documentation.

Depending on your preference, run one of the following.

# With npm
$ npm install --save-dev @sumup/foundry

# With yarn
$ yarn add --dev @sumup/foundry


Once you have installed Foundry, you should bootstrap configuration files the CLI tools you would like to use through Foundry and set up scripts in you package.json to actually run them.

Bootstrap configuration files

Foundry exposes customizable configuration presets for the CLI tools it supports. To make use of these presets, you need to bootstrap a configuration file for each tool you would like to use. This is done with the bootstrap-config command. Foundry supports different presets for each tool, base being the default preset. You can specify the tool you would like to use as a flag, the preset as the flag’s value.

# Bootstraps the eslint and prettier config files using the react preset for ESLint and the default (base) preset for prettier.
$ npx foundry bootstrap-config --eslint react --prettier

Running a tool through Foundry

Foundry manages all supported CLI tools for you and exposes them via the run command. To run ESLint through Foundry execute npx foundry run eslint src from the terminal. Here, src is the folder you want ESLint to check. Note that you can use any of the command line flags and arguments supported by ESLint and other tools. Foundry simply forwards them and they get handled by the tool. For example, to have ESLint fix your linting errors, run npx foundry run eslint --fix src.

Use Foundry for your package.json scripts

For automation purposes and easier access, you will want to alias frequently used commands as scripts in your package.json. Here are some examples.

"scripts": {
    "lint": "foundry run eslint --fix src",
    "create-component": "foundry run plop component"

List of commands

At the moment, Foundry supports two commands; bootstrap-config and run. They allow you to create configurations and run the cooresponding tools. The tools we support are ESlint (with Prettier), Plop, Husky, and lint-staged. We will add more documentation here. For now, you can try foundry --help or foundry {command} --help to se your options.

List of configuration presets

Here is a list of supported presets for the bootstrap-config command, grouped by CLI tool.

ESLint (--eslint flag)

We lint our code with ESLint. Linting our code helps us spot mistakes early. You can inspect all presets in the respective config file.

  • base: the default preset. Uses the airbnb-base, prettier, and jest/recommended presets, prettier and jest plugins and some configurations.
  • node: like base but specifies node as environment.
  • react: like base but adding the react/recommended, jsx-a11y/recommended, and prettier/react presets.

Prettier (--prettier flag)

Prettier is our code formatter of choice. It makes all our code look the same after every save. We only have a base preset, which follows our default formatting rules.

Plop (--plop flag)

Plop allows us to quickly create a set of files, e.g. for a React component, with a single command. This is very helpful when creating a lot of components and reduces the boilerplate you have to write as a developer.

Currently, we only have a plop generator for React components. Use the react preset for that.

Custom templates

This is an advanced use case.

Plop uses Handlebar templates to generate the files. If you'd like to override a built-in template, you can specify a custom template directory and extension. Plop will first check if a custom template exists, otherwise, it will fallback to the default template.

In order to specify the template directory or extension, you need to modify the config file (plopfile.js) that was generated by foundry bootstrap-config --plop, like so:

- module.exports = require('@sumup/foundry/plop').react;
+ const configFn = require('@sumup/foundry/plop').react;
+ const opts = {
+   // The path should be relative to the location of the plopfile.js.
+   templateDir: <path-to-templates>
+   // The extension without a leading period, defaults to 'js' .
+   templateExtension: <file-extension>
+ }
+ module.exports = plop => configFn(plop, opts);

To see which variables are available for use in a Handlebars template, have a look at the default templates.

lint-staged (--lint-staged flag)

lint-staged is a tool for running linters on files staged for your next commit in git. Together with Husky, it makes ensuring bad code gets committed very easy.

lint-staged only comes with a base preset.

Husky (--husky flag)

Husky makes setting up git hooks consistently very easy. Whenever someone installs your project, husky will automatically set up git hooks as part of its postinstall script.

Husky only comes with a base preset.

semantic-release (--semantic-release flag)

semantic-release automates the whole package release workflow including: determining the next version number, generating the release notes and publishing the package.

  • base: the default preset. Analyzes the commit history, generates release notes and publishes them to GitHub.
  • modules: like base but also publishes the code to npm. For node modules.



Creating and maintaining a JavaScript project can be very tedious. There are tools, configurations, dependency management, and boilerplate. With Foundry, you can fix all of that with a single dependency. It lints, creates files, links configurations, and (soon) runs your build. And the best part? You can still get down and dirty with your configurations. But only if you want.

The problem

Setting up and maintaining a complex JavaScript project can be very tedious.There are many different dependencies to install (linters, testing frameworks, bundlers) and configurations to set up. Once you have a running project, you end up writing a lot of boilerplate code when creating commonly used files. For example, a React component might come with a spec file (test), a Storybook file (isolated component development), and a service for handling business logic.

It gets much, much worse when you have several (many?) projects. What happens, when there is a breaking change in a tooling dependency? What if team decides you need to add a new linting rule? Nobody wants to go through every project and update those files all the time. And who knows, if they are even the same? Syncing configurations is terrible. Or think about that new engineer you are onboarding. How are they supposed to know how you structure your project, how your components are supposed to look, which files they need to create?

You might think you could solve these issues with a boilerplate repository and some snippets or templates. But you cannot. At least the maintenance problem will not go away.

The solution

Toolkits are a way to mitigate these kinds of problems. They encapsulate as much as possible of the your toolchain into a single dependency and expose it through a CLI. Doing so gets you the following, probably more!

  • You don't need to set up any tooling when creating a new project. Bootstrap it and start coding. 🚀
  • When you need to update a tooling dependency or change a configuration, do it in the toolkit and update the toolkit dependency in your projects — preferably in an automated fashion. That's it.
  • Make the way you write JavaScript more consistent. All your projects will work exactly the same. 📏
  • Easy onboarding. New colleagues will be able to get productive much more quickly. 🙇‍♂
  • The number of direct dependencies becomes much smaller and your package.json shorter. 🕸

But what makes Foundry different?

We were inspired by many toolkit projects, such as create-react-app and kcd-scripts. These projects are opinionated, and so is Foundry. But Foundry is different, in our opinion, because:

  • It encapsulates tools and their configurations, but also lets you get down and dirty with the configs in your project.
  • It merely proxies the tools you use on a CLI level instead of talking to them through their Node.js APIs. We literally execute the binaries and forward any options you provided.

So please, go ahead and try it.

Code of Conduct (CoC)

We want to foster an inclusive and friendly community around our Open Source efforts. Like all SumUp Open Source projects, this project follows the Contributor Covenant Code of Conduct. Please, read it and follow it.

If you feel another member of the community violated our CoC or you are experiencing problems participating in our community because of another individual's behavior, please get in touch with our maintainers. We will enforce the CoC.


About SumUp

SumUp logo

It is our mission to make easy and fast card payments a reality across the entire world. You can pay with SumUp in more than 30 countries, already. Our engineers work in Berlin, Cologne, Sofia and Sāo Paulo. They write code in JavaScript, Swift, Ruby, Go, Java, Erlang, Elixir and more. Want to come work with us? Head to our careers page to find out more.

You can’t perform that action at this time.