moker
No more struggles setting up a new JavaScript repository. Kick-start
single-purpose repos, monorepos, monorepo workspaces and common tooling:
yarn dlx moker create --monorepo my-monorepo
cd my-monorepo
yarn moker use prettier doctoc semantic-release
yarn moker add --template express server
yarn moker add --template cra client
yarn moker add --template lib shared
yarn moker add --template bandersnatch cli
Features
- 👢 Kick-start a new repo or monorepo using Yarn
- 🧰 Plugins to use pre-configured common tooling
- ➕ Quickly add workspaces to a monorepo
- 🧬 Workspace templates for a shared library, React app, API or CLI
- ⚡ Extensible, bring your own plugins
🤓 Default: The core plugins make some assumptions you may not agree with.
If that's the case, this tool is probably not for you. The defaults used are
documented below and marked with a nerd-face emoji so you should be able to
get a clear picture of what to expect.
Table of contents
Getting started
Prerequisites
You will need Node v18+ and Yarn v2+ in order to use moker
.
Usage
moker
is distributed as a NPM package, and can be run with yarn dlx
:
yarn dlx moker <command>
Note: Note that when we use yarn dlx moker
to create a new repo, moker
is added as a dependency to your new repo, so we can simply use yarn moker
to execute commands from within the repo directory.
Creating a single-purpose repo
To create a new repo in the my-repo
directory:
yarn dlx moker create my-repo
Creating a monorepo
To create a new monorepo in the my-monorepo
directory: :
yarn dlx moker create --monorepo my-monorepo
🤓 Default: The monorepo is initiated with Yarn without Zero-Installs and in
legacy nodeLinker: node-modules
mode because a lot of packages are not yet
compatible with PnP or require a workaround.
Creating a monorepo workspace
Workspaces (a.k.a. monorepo packages) are added in a customizable subdirectory
of the monorepo (the default is packages
). To add a new workspace called
my-workspace
to your monorepo, run this from within the monorepo directory:
yarn moker add my-workspace
Using plugins
Plugins are used to add additional tools to your repo or workspace. Add the
prettier
plugin with:
yarn moker use prettier
Plugins may work together. For example, lint-staged
will install a pre-commit
hook which formats code if prettier
and husky
are installed. The order in
which plugins are added does not matter. You can install multiple plugins at
once:
yarn moker use prettier lint-staged husky
Note: Some plugins only work at the repo or workspace level, moker
will
warn you if you try to add a plugin at the wrong level.
For a complete list of out-of-the-box plugins, see the section
available plugins. Using 3rd party plugins is also
supported:
yarn add --dev --exact moker-plugin-name
yarn moker use moker-plugin-name
Using templates
Templates are pre-defined collections of plugins and scaffolding to quickly
create focussed new repos or workspaces. To create a new repo my-repo
with the
common
template:
yarn dlx moker create --template common my-repo
To add a workspace called shared
to a monorepo using the lib
template:
yarn moker add --template lib shared
You can install multiple templates at once:
yarn dlx moker create --template common --template github-action my-action
For a complete list of out-of-the-box templates, see the section
available templates. Using 3rd party templates is also
supported:
yarn dlx --package moker-template-name \
moker create --template moker-template-name my-repo
Using plugins and templates together
Plugins and templates can be used together, for example:
yarn dlx moker create --template express --use prettier my-repo
Available plugins
dependabot
Scope: repo
This plugin adds a Dependabot configuration to your monorepo with an updater
for NPM packages.
If you have the github-actions
plugin installed, it will add an updater for
GitHub Actions workflows.
devcontainer
Scope: repo
This plugin creates a Development Containers
configuration using the
typescript-node
image.
If you have the prettier
plugin installed, it will add the Prettier VS Code
extension.
doctoc
Scope: repo
This plugin adds a script to generate a table of contents for the README using
doctoc.
If you have the husky
plugin installed, it will also add a pre-commit hook.
esbuild
Scope: repo or workspace
This plugin sets up esbuild and adds a build
and
build:watch
script to the repo or both the workspace and the monorepo.
🤓 Default: If you have the typescript
plugin installed as well, we'll
assume that you want to build to a bundle instead of transpiled TypeScript. We
will still use tsc
for type checking.
github-actions
Scope: repo
This plugin creates a simple ci.yml
GitHub Actions workflow and a workflow to
update the Node versions
periodically.
If you have the prettier
plugin installed, this will also setup a lint.yml
workflow.
If you have the semantic-release
plugin installed, this will also setup a
release.yml
workflow. This workflow needs these secrets to be added to your
repository:
GH_PAT
: a GitHub token with read/write access to your repositoryNPM_TOKEN
: an NPM token with publish access to your packages
If you have the dependabot
plugin installed, this will also setup two
additional workflows. A dependabot-automerge
workflow which enables auto-merge
(squash) on dependabot PRs. You need to enable Allow auto-merge in the GitHub
repository settings and apply Branch protection rules for the main branch.
Note: If you enabled Require approvals in the branch protection rules,
this won't automatically approve the PR. You will need to add an additional
command to the workflow, like:
steps:
- - run: gh pr merge --auto --squash "$PR_URL"
+ - run: |
+ gh pr review --approve "$PR_URL"
+ gh pr merge --auto --squash "$PR_URL"
env:
A reload-moker-plugins
workflow is added to reload the moker plugins and
create a pull request with changes made by moker whenever dependencies are
updated by dependabot.
🤓 Default: The workflows will use the main
branch by default, but it is
trivial to change this.
husky
Scope: repo
This plugin sets up Husky at the repo
level.
Warning: The postinstall
script to install Husky automatically is only
installed on (private) monorepos. Otherwise, postinstall
will run when
someone installs your package and result in an error.
See
Husky docs on installing with Yarn 2
jest
Scope: repo or workspace
🧪 Experimental Currently only works with the typescript
plugin. Currently
doesn't work when you have ESM dependencies in node_modules
.
This plugin sets up Jest and adds a test
and test:watch
script to the repo or both the workspace and the monorepo.
lint-staged
Scope: repo
This plugin sets up lint-staged at the
monorepo level.
If you have the prettier
plugin installed, this will setup a task to format
staged files using prettier --write --ignore-unknown
.
If you have the husky
plugin installed, this will setup a pre-commit hook to
run yarn lint-staged
.
prettier
Scope: repo
This plugin sets up Prettier.
🤓 Default: Prettier is installed with this configuration:
proseWrap: always
We only set this proseWrap
override because we think markdown files should
always be truncated to match whatever the printWidth
setting is. This makes
it so much easier to read and write markdown files!
semantic-release
Scope: repo
This plugin sets up
semantic-release. It
uses the
semantic-release-yarn plugin
which has support for releasing monorepos.
Please note that by default the root repository is not published. You can change
this by setting the private
property in package.json
to false
.
🤓 Default: The release configuration will use the main
branch by default,
but it is trivial to change this.
test
Scope: repo or workspace
This plugin enables testing with the native
node --test functionality.
When the typescript
plugin is also installed, it will use
ts-node to load TypeScript test files.
todos
Scope: repo or workspace
This plugin adds a script to generate a TODO markdown file from all code
annotations using leasot.
If you have the husky
plugin installed, it will also add a pre-commit hook.
typescript
Scope: repo or workspace
🧪 Experimental Since v2, this plugin uses the new --build
mode of
TypeScript, which makes building a lot faster but may require some additional
configuration.
This plugin sets up TypeScript and adds a
build
and build:watch
script to the repo or both the workspace and the
monorepo.
In addition, this will add a typescript
and typescript:watch
script to the
monorepo which can use
project references
to build workspaces which depend on each other faster and provides a better
developer experience.
In order to use this, add all TypeScript workspaces to tsconfig.json
in the
monorepo root directory:
{
"$schema": "https://json.schemastore.org/tsconfig",
"references": [
{ "path": "./packages/some-library" },
{ "path": "./packages/some-dependency" }
],
"files": []
}
And reference dependant workspaces in the workspace tsconfig.json
:
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"rootDir": "src",
"outDir": "dist",
"declarationDir": "types"
},
"references": [{ "path": "../some-dependency" }],
"include": ["src/**/*"]
}
You can optionally sync project references with
yarn dlx @monorepo-utils/workspaces-to-typescript-project-references
.
xv
Scope: repo or workspace
🧪 Experimental Currently only works with the typescript
plugin.
This plugin sets up xv and adds a test
script to the repo or both the workspace and the monorepo.
Available templates
angular
Scope: workspace
Uses the Angular CLI to interactively scaffold
an Angular app (web client).
bandersnatch
Scope: repo or workspace
Scaffolds a simple bandersnatch CLI
app tool with the typescript and
jest plugins.
common
Scope: repo
This is the only monorepo template at this point. It simply installs all
available monorepo plugins.
cra
Scope: workspace
Uses create-react-app to scaffold a React.js
app (web client).
express
Scope: repo or workspace
Scaffolds a simple express HTTP app with the
typescript and jest plugins.
github-action
Scope: repo
🧪 Experimental
Scaffolds a custom GitHub Action template.
lib
Scope: repo or workspace
A plain shared library template with the typescript and
jest plugins.
nestjs
Scope: workspace
Uses the
TypeScript starter project to
scaffold a Nest.js server app.
next
Scope: workspace
Uses
create-next-app
to scaffold a Next.js app.
sanity
Scope: workspace
Uses create-sanity which
interactively scaffolds a Sanity Studio package.
Commands
See moker --help
for a list of available commands.
Contributing
Contributions are very welcome!
Roadmap
Also see TODO.md.
Development
To run the moker
CLI from source, run:
yarn start
Note that you can create a new monorepo for testing purposes outside the current
working directory with:
yarn start create /path/to/my-repo
Devcontainer
A devcontainer configuration is included in this repo to
get started quickly.
Credits
©️ Copyright 2022 Joram van den Boezem
♻️ Licensed under the MIT license
🤔 Moker? MOnorepo KickstartER