Usage Guide¶
How to install, configure, and use @shibanet0/datamitsu-config in your projects.
Installation¶
Choose one of three installation methods based on your use case:
Method 1: npm/pnpm Package (Recommended)¶
Install the package as a dev dependency:
After installation, the postinstall script automatically builds the config. You can then initialize datamitsu in your project:
This installs managed tool binaries. To initialize configuration files, run:
This creates all necessary configuration files for the managed tools in your project.
For existing pnpm-workspace.yaml files, reconciliation also migrates the legacy
trustPolicy.allowDowngrade list to trustPolicyExclude:
Existing trustPolicyExclude entries are retained and duplicates are removed when
merging the lists. Package selectors keep their versions and ranges. Repeating
reconciliation preserves the result; modern scalar trustPolicy values are left intact.
Malformed exclusion lists stop reconciliation with an error.
Reconciliation also brings the file up to pnpm 12, which fails every command on a workspace
setting it does not recognize. The settings pnpm 12 removed — confirmModulesPurge,
ignoreDepScripts, ignorePatchFailures, managePackageManagerVersions,
packageManagerStrict, packageManagerStrictVersion and useNodeVersion — are dropped,
allowNonAppliedPatches becomes allowUnusedPatches with its value, and auditLevel gives way to
audit.level. Everything else under audit, such as the audit.ignore list, is kept.
pnpm 12 records the packageManager version in pnpm-lock.yaml. The managed package.json pins
the pnpm version this package ships with, so a reconciliation that moves it leaves the lockfile out
of date, and pnpm install --frozen-lockfile fails in CI. Run pnpm install after reconciling and
commit pnpm-lock.yaml together with package.json.
When to use:
- Standard development workflow
- Projects using npm/pnpm for dependency management
- When you need the npm package ecosystem integration
Method 2: Docker Images¶
Pre-built Docker images with all tools pre-installed for fast, consistent CI/CD.
Stable releases (Debian default):
# Pull latest stable
docker pull ghcr.io/shibanet0/datamitsu-config:latest
# Pull specific version (recommended for CI)
docker pull ghcr.io/shibanet0/datamitsu-config:0.0.4
Stable releases (Alpine, smaller image):
# Latest stable Alpine
docker pull ghcr.io/shibanet0/datamitsu-config:latest-alpine
# Specific version Alpine
docker pull ghcr.io/shibanet0/datamitsu-config:0.0.4-alpine
Unstable builds (bleeding edge):
# Latest unstable (Debian)
docker pull ghcr.io/shibanet0/datamitsu-config-unstable:unstable
# Latest unstable (Alpine)
docker pull ghcr.io/shibanet0/datamitsu-config-unstable:unstable-alpine
The PR workflow builds both image variants and runs an offline smoke test for each. Each variant has its own build-cache scope; its smoke test reuses that same scope.
Docker image features:
- All tools pre-installed (via
datamitsu init --all) — faster startup - Multi-platform support: linux/amd64, linux/arm64
- Base configuration via
--before-configflag (allows project config to override) - Stable registry (
ghcr.io/shibanet0/datamitsu-config): latest/latest-alpine— latest stable releasestable/stable-alpine— same as latest- Semver versions:
0.0.4,0.0.4-alpine - Unstable registry (
ghcr.io/shibanet0/datamitsu-config-unstable): unstable/unstable-alpine— latest unstable build- Date-tagged:
unstable-YYYYMMDD-SHA,unstable-YYYYMMDD-SHA-alpine
Usage examples:
# Run all checks in current directory
docker run --rm -v "$(pwd):/workspace" \
ghcr.io/shibanet0/datamitsu-config:latest check
# Run with Alpine (smaller image)
docker run --rm -v "$(pwd):/workspace" \
ghcr.io/shibanet0/datamitsu-config:latest-alpine check
# Run specific tool
docker run --rm -v "$(pwd):/workspace" \
ghcr.io/shibanet0/datamitsu-config:latest exec eslint -- src/
# Use in CI with version pinning (CI=true: see "CI/CD integration" below)
docker run --rm -e CI=true -v "$(pwd):/workspace" \
ghcr.io/shibanet0/datamitsu-config:0.0.4 check
# Override with local project config (config merging)
docker run --rm -v "$(pwd):/workspace" \
ghcr.io/shibanet0/datamitsu-config:latest \
--config /workspace/datamitsu.config.js check
When to use:
- CI/CD environments without Node.js dependency management
- Consistent tooling across different environments and platforms
- Fast CI runs (tools are pre-installed, no download time)
- Multi-platform builds (amd64, arm64)
Container configuration merging:
The Docker images use the --before-config flag in the ENTRYPOINT, which loads the container's config as a base layer. This allows your project's datamitsu.config.js to override or extend the base configuration when you pass --config /workspace/datamitsu.config.js.
Container registries:
Method 3: Remote Config¶
Reference this config as a remote base configuration in your project. datamitsu supports remote configs for centralized configuration management.
Create datamitsu.config.js in your project:
function getRemoteConfigs() {
return [
{
url: "https://github.com/shibanet0/datamitsu-config/releases/download/v0.0.4/datamitsu.config.js",
hash: "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2", // SHA-256 hash
},
];
}
function getConfig(config) {
// config contains merged configuration from remote
return {
...config,
// Add project-specific overrides here
};
}
globalThis.getRemoteConfigs = getRemoteConfigs;
globalThis.getConfig = getConfig;
globalThis.getMinVersion = () => "1.0.0";
Get the SHA-256 hash for verification:
Every remote config requires a SHA-256 hash for security. Get it from the releases page or compute it:
VERSION=v0.0.4
curl -sL "https://github.com/shibanet0/datamitsu-config/releases/download/${VERSION}/datamitsu.config.js" | sha256sum
Then use datamitsu normally:
When to use:
- Projects that don't use npm/pnpm
- Centralized configuration across multiple repositories
- Teams wanting to inherit a base configuration and customize per-project
- CI/CD environments with datamitsu already available
How it works:
- Remote config is fetched and verified against SHA-256 hash
- Configuration is cached locally in
{store}/.remote-configs/ - Your local
getConfig()receives the merged config from remote - You can override or extend the remote configuration locally
Security features:
- SHA-256 hash verification is mandatory
- HTTPS-to-HTTP redirects are rejected
- 30-second timeout and 10 MiB size limit
Important:
- Pin to a specific version (not
latest) since the hash changes with each release - Update the hash in your config when upgrading to a new version
- See remote configs guide for advanced usage (inheritance chains, wrapper packages)
Browse all releases with SHA-256 hashes at GitHub Releases.
Basic Usage¶
Running checks¶
Run all configured linters and formatters in one pass:
This executes fixers (formatters, auto-fixes) followed by linters (type checking, ESLint, etc.). It should complete with no errors on a clean codebase.
Running a specific tool¶
Execute any managed tool directly:
For example, to run ESLint:
To list all available tools:
Configuration¶
TypeScript¶
This package includes reusable tsconfig presets. Extend them in your tsconfig.json:
Available presets:
| Preset | Use Case |
|---|---|
base.json |
Any TypeScript project |
library.json |
Standalone libraries |
react-library.json |
Standalone React libraries |
service.json |
Backend services (Node.js) |
service-worker.json |
Backend services (Cloudflare Workers) |
shared-library.json |
Libraries in a monorepo |
shared-react-library.json |
React libraries in a monorepo |
nextjs.json |
Next.js applications |
infra-pulumi.json |
Pulumi / Infrastructure-as-Code |
Git Hooks¶
datamitsu integrates with lefthook for git hooks. After pnpm dm init, hooks are configured automatically:
- pre-commit — runs
dm check --file-scopedon staged files, regenerates docs, and runs tests (sequentially) - commit-msg — validates commit messages with commitlint (Conventional Commits)
- post-checkout — reinstalls dependencies and reinitializes datamitsu
Customizing Tool Behavior¶
Individual tools (ESLint, Prettier, cspell, etc.) can be customized through their standard config files. datamitsu respects these files when present in your project root:
eslint.config.mjs— ESLint configuration.prettierrc/prettier.config.mjs— Prettier configurationcspell.json— cspell dictionary and settingsknip.config.js— Knip unused code configuration
Configs that only their tool reads — gitleaks, yamlfmt, yamllint, hadolint and a few more — are not
written into your repository: dm init keeps them in .datamitsu/configs/. To change one, name its
tool in your datamitsu.config.* and reconcile it into the repository:
function getConfig(config) {
return { ...config, ejectConfigs: ["gitleaks"] };
}
globalThis.getConfig = getConfig;
Naming checks are opt-in and split between two tools: alint checks file names, ls-lint checks
directory names. Enable either with tools["alint"].skip: false or tools["ls-lint"].skip: false,
then run pnpm dm init and pnpm dm config reconcile so both the managed base in .datamitsu/
and your own file exist.
.alint.ymlextends.datamitsu/alint-managed.yml. Redefine a rule by itsid(for examples0-js-ts-file-names) to narrow it. Keepallow_out_of_root: true: the managed file is linked from outside the repository..ls-lint.ymllayers over.datamitsu/ls-lint-managed.yml.ignoreadds exclusions, and a literal path such asapps/web/src/generatedis free. Redefining.dirreplaces the base rule, so includeregex:\.[a-z0-9_-]+to keep dot-directories valid.
Adopting Knip on an existing codebase¶
Everything here works on a new project with no configuration. The exception is Knip, and only because it reports debt that predates it: on a codebase that has never run it, unused files and exports arrive by the hundred, and the gate is red from day one.
adopted phases that in. Everything outside the list is switched off, so the gate stays green while
the debt is still there:
correctness reports defects rather than debt — imports that do not resolve, dependencies used but
never declared — and stays small at any age. Widen it one group at a time (dependencies, files,
exports) until the option can go. Once most of a group passes, prefer ignoreIssues over dropping
the group again, so new code stays covered:
Overrides extend the shared configuration rather than replacing it. To replace something instead, pass a function — it receives the base configuration and returns the final one.
Common Workflows¶
Setting up a new project¶
# Install the package
pnpm add -D @shibanet0/datamitsu-config
# Install tool binaries
pnpm dm init
# Initialize configuration files
pnpm dm config reconcile
# Run all checks to verify the configuration
pnpm dm check
Adding to an existing project¶
# Install
pnpm add -D @shibanet0/datamitsu-config
# Install tool binaries
pnpm dm init
# Initialize configuration files
pnpm dm config reconcile
# Check for issues — expect some on first run
pnpm dm check
# Fix issues iteratively, or auto-fix what can be auto-fixed
pnpm dm check
CI/CD integration¶
In CI pipelines, run checks after install:
Method 1: npm/pnpm (traditional):
# GitHub Actions example
- run: pnpm install
- run: pnpm dm init # needed if postinstall was skipped (e.g. --ignore-scripts)
- run: pnpm dm check
datamitsu handles binary installation during pnpm dm init, which runs automatically as part of postinstall. In CI environments that use --ignore-scripts, run pnpm dm init explicitly.
Method 2: Docker (faster, no dependencies):
# GitHub Actions example with Docker
- name: Run datamitsu checks
run: |
docker run --rm -e CI=true -v "${{ github.workspace }}:/workspace" \
ghcr.io/shibanet0/datamitsu-config:0.0.4 check
-e CI=true is not optional. Some tools run only in CI — their status in the
tools reference reads "runs in CI only" — and they recognize CI by the CI
variable, which docker run does not forward from the runner. Without it they are skipped, in CI
as well as locally.
Docker advantages in CI:
- No npm install or binary download time (tools pre-installed in image)
- Consistent environment across all CI runs
- Faster cold starts
- No Node.js version management needed
Troubleshooting¶
Bootstrap problem: missing datamitsu.config.js¶
If you see an error like "no such file or directory: datamitsu.config.js", the config file needs to be built first. This happens after a fresh clone or if the file was deleted.
Run the bootstrap command:
This builds the config from source, moves it to the project root, and runs pnpm dm init.
pnpm dm command not found¶
Ensure the package is installed as a dev dependency:
The dm binary is provided by this package. Verify it exists:
Tool binary not found¶
If a specific tool fails to run, reinitialize to download its binary:
Checks failing on first run¶
This is expected when adding datamitsu to an existing project. Run pnpm dm check repeatedly — many issues are auto-fixed on each pass. For remaining issues, review the output and fix manually.
Further Reading¶
- Apps — full list of managed apps with versions and links
- datamitsu documentation — comprehensive docs for the datamitsu tool manager
Lefthook configuration formatting¶
pnpm dm check sorts Lefthook configuration files with lefthook-sort, which runs on the managed Bun runtime. Datamitsu provisions Bun automatically; a system Bun installation is unnecessary. To sort a configuration explicitly:
The sorter preserves comments and orders hooks by lifecycle and commands by priority. Configuration validation runs separately through lefthook validate.
JavaScript and TypeScript tool runtimes¶
pnpm dm check runs ESLint, oxlint, and oxfmt on the pinned Bun runtime. Datamitsu installs Bun and each tool's locked dependencies automatically. The same runtime is used when these managed apps run from Git hooks.
With the pinned Bun 1.4.1, ESLint can report a shifted column for TypeScript syntax errors: export const broken = ; is reported at column 16 instead of 22. The error message and failure status are preserved.
Svelte¶
.svelte needs nothing configured. oxfmt formats components in every project, and oxlint reads the <script> block; ESLint adds eslint-plugin-svelte as soon as svelte (or @sveltejs/kit) is in the project's package.json, because its rules only mean something where components exist. stylelint lints the <style> block too, so a Svelte project gets CSS checks without naming anything either.
The svelte compiler all of them need ships with the managed tools rather than being resolved from the project.