DX for Developer Experience
dx-flow is a Node CLI that bootstraps code quality, Git hooks, versioning, and release workflows for JS/TS projects.
Official package: @keyobs/dx-flow
This repository is public and can be forked freely. Only Keyobs publishes the official package under the @keyobs scope. Forks should publish under their own GitHub Packages scope.
- BiomeJS: Linter and formatter.
- Husky: Git hooks manager, automates script execution on commit/push.
- CommitLint: Commit message guard (enforces conventional standards).
dx-flow can be executed via npx from GitHub Packages.
Run dx-flow in a consuming app
npx @keyobs/dx-flow@latest run
The setup asks for:
- the target framework
- the install mode
Install modes:
copy: default mode; copies QA and release scripts into the consuming project.dependency: installs@keyobs/dx-flowas a dev dependency; QA and release scripts run through thedx-flowbinary.
In both modes, Husky hooks are copied into the consuming project so they stay visible and editable.
Non-interactive examples:
npx @keyobs/dx-flow@latest run --mode copy
npx @keyobs/dx-flow@latest run --mode dependency
Available CLI commands:
dx-flow run
dx-flow qa:new
dx-flow qa:validate
dx-flow qa:reset
dx-flow release patch
dx-flow release minor
dx-flow release major
dx-flow commit --skip-tests -m "..."
Update dx-flow to the latest version (global) and run
# Update the package version
npm i -g @keyobs/dx-flow@latest
# Overwrite a pre-existing config:
npx @keyobs/dx-flow run --force
- Dependencies: Installs Biome, Husky, Commitlint, and lint-staged.
- Configs: Deploys
biome.jsonandcommitlint.config.js. - Git Hooks: Configures Husky hooks for validation.
- Scripts: Adds
lint,format,check, andpreparetopackage.json. - Modes: Supports copied scripts or a managed
@keyobs/dx-flowdependency.
Supported package managers:
- npm
- pnpm
- yarn
- bun
Package manager support is based on project lockfiles. Hooks use the detected package manager for lint-staged, jest, tsc, and test:run.
- Main Branch: Blocks direct commits and pushes to
main. - Secrets: Blocks commits containing
.envfiles. - Types: Runs
tsc --noEmitbefore committing. - Tests: Enforces
test:runbefore pushing todevelop. - Commits: Validates conventional commit formats.
- Skip tests on commit:
dx-flow commit --skip-tests -m "..."
skips pre-commit tests only (lint and typecheck still run).
Husky hook templates are the single source of truth:
scripts/ts/templates/.husky/commit-msg
scripts/ts/templates/.husky/pre-commit
scripts/ts/templates/.husky/pre-push
These files are copied as-is into consuming projects in both copy and dependency modes. When a hook already exists, dx-flow asks before overwriting it. Use --force to overwrite without prompts.
The same overwrite rule applies to managed config files such as biome.json and commitlint.config.mjs.
.
├── bin/
│ └── dx-flow.sh # CLI entry point and path resolver
| dx-flow.mjs
├── scripts/
│ ├── git # Git helper commands
│ ├── qa # QA scripts
│ ├── dx-flow-setup.mjs # Main controller and framework selector
│ └── ts/
│ ├── setup-ts.mjs # Technical setup script for TypeScript
│ └── templates/ # Tool configuration templates
│ ├── *framework* # specific config for a framework
│ ├── commitlint.config.js # Commit validation rules
│ └── .husky/ # Git hook templates
│ ├── pre-commit # Branch protection and linting
│ ├── pre-push # Test validation
│ └── commit-msg # Commit message enforcement
└── test/ # Node test runner tests
DX-FLOW uses SemVer logic.
These commands bump the version, tag, and commit locally.
| Command | Target | Result |
|---|---|---|
npm run release:patch |
Bug fixes | 1.0.0 → 1.0.1 |
npm run release:minor |
New features | 1.0.0 → 1.1.0 |
npm run release:major |
Breaking changes | 1.0.0 → 2.0.0 |
Direct CLI commands:
dx-flow release patch
dx-flow release minor
dx-flow release major
Windows note
If you run npm version manually on Windows (PowerShell/cmd), use double quotes for the message:
npm version patch -m "chore(release): %s"
Release candidate
| Command | use | Result |
|---|---|---|
npm run qa:new |
Add -x then autoincrement | 1.0.0 → 1.0.0-0 |
npm run qa:validate |
Delete -x | 1.0.0-3 → 1.0.0 |
npm run qa:reset |
Delete -x | 1.0.0-3 → 1.0.0 |
qa:validate and qa:reset run the same command; both names stay for dev convenience.
Direct CLI commands:
dx-flow qa:new
dx-flow qa:validate
dx-flow qa:reset
DX-FLOW is published as the official private package @keyobs/dx-flow on GitHub Packages.
Configure npm-compatible clients to use GitHub Packages for the @keyobs scope:
@keyobs:registry=https://npm.pkg.github.com
Authenticate with a GitHub personal access token that has package permissions:
npm login --scope=@keyobs --auth-type=legacy --registry=https://npm.pkg.github.com
For personal machines, you can also keep the token in your user-level npm config:
//npm.pkg.github.com/:_authToken=TOKEN
In dependency mode, dx-flow adds the registry line to the consuming project's .npmrc if it is missing. It never writes a token.
If installing @keyobs/dx-flow fails, dx-flow offers to continue in copy mode.
The repository can be public, but the official package distribution is controlled by the @keyobs scope on GitHub Packages.
Publishing is automated by GitHub Actions when a version tag is pushed:
npm run release:minor
git push
git push --tags
The tag must match the package.json version. For example, tag v3.1.0 publishes package version 3.1.0.
Manual publish is still available:
npm run publish:github
The prepublishOnly check blocks accidental publication unless:
- package name is
@keyobs/dx-flow - registry is
https://npm.pkg.github.com originpoints tokeyobs/dx-flow
Forks should change the package name and repository before publishing under their own scope.
️⚠
1. In dx-flow root directory :
dx-flow binary already exists, remove it before linking:
npm unlink -g @keyobs/dx-flow
# or remove the binary directly:
# rm -f "$(npm bin -g)/dx-flow"
#
# PowerShell:
# Remove-Item -Force "$(npm bin -g)\\dx-flow.cmd"
#
# PowerShell (Cmd shim + global node_modules):
# Remove-Item -Recurse -Force "$(npm root -g)\\@keyobs\\dx-flow" 2>$null
Create a symlink :
# run at start
npm link
Create / Update the package :
# run at every change
npm pack
Run local checks:
npm run check
npm test
2. In client app :
dx-flow run
🪲 Debug
In local dev mode, if the install exits with error, try refresh the node modules.
Clean node modules :
#PowerShell:
Remove-Item -Recurse -Force node_modules, package-lock.json
npm cache clean --force
#Linux/macos
rm -rf node_modules package-lock.json
npm cache clean --force