Core Concepts
datamitsu is built around five core concepts: binary management, runtime management, managed configs, the tooling system, and configuration layers.
Binary Management
datamitsu downloads, verifies, and stores tool binaries per platform. Every binary must have a SHA-256 hash — datamitsu refuses to download anything without one.
Binaries are kept at ~/.cache/datamitsu/store/.bin/{name}/{configHash} and reused across runs. The internal store key is derived from the binary info and resolved target, so changing a version, hash, OS, architecture, or libc selects a fresh entry.
Supported archive formats include: tar.gz, tar.xz, tar.bz2, tar.zst, zip, and raw binaries.
App Types
datamitsu supports seven types of applications:
| Type | Description | Example Tools |
|---|---|---|
binary | Self-managed binaries with URLs and hashes | golangci-lint, hadolint, shellcheck |
bun | npm packages installed and run with Bun | eslint |
uv | Python packages via managed UV runtime | yamllint, ruff |
node | npm packages via managed Node.js + pnpm | eslint, prettier, spectral |
jvm | JVM applications via managed JDK | openapi-generator-cli |
go | Go tools built from source via managed SDK | govulncheck |
shell | Shell commands with custom environment | custom scripts |
Runtime Management
For tools that need a language runtime (Bun, Python, Node.js, Java, or Go), datamitsu manages the runtime itself. This provides complete isolation — each app gets its own environment with pinned dependencies.
How Runtimes Work
- Managed mode — datamitsu downloads the runtime binary (Bun, UV, Node.js, JDK, or Go SDK) with hash verification
- System mode — Uses a runtime already installed on your system
Each runtime-managed app gets an isolated directory at
~/.cache/datamitsu/store/.apps/{kind}/{app}/{hash}/. The internal key includes
the effective runtime and app configuration, lock and managed-content inputs,
and applicable target dimensions (OS, architecture, and libc), so a relevant
change produces a fresh environment.
Runtime Types
- Bun — Downloads and verifies a pinned Bun archive, runs the shared pnpm installer with Bun, and executes JavaScript entrypoints with Bun
- UV (Python) — Downloads UV, optionally pins a Python version, creates an isolated project environment with
pyproject.toml+uv sync - Node (Node.js) — Downloads and verifies (SHA-256) a pinned Node.js archive and extracts it, downloads pnpm from the npm registry, runs
pnpm installin isolated app directories - JVM (Java) — Downloads Temurin JDK, extracts the full JDK tree, downloads JAR files with hash verification, executes via
java -jar - Go — Downloads and verifies (SHA-256) a pinned Go SDK, builds tools from source with
go build -trimpath -mod=readonlyagainst ago.mod+go.sumlock file
Lock Files
Bun, Node, UV, and Go apps require lock files (pnpm-lock.yaml for both JavaScript runtimes,
uv.lock, or a go.mod + go.sum payload). Normal config loading rejects a runtime-managed
app without one. Lock content can be embedded compactly with brotli compression.
Generate a lock file:
datamitsu config lockfile <appName>
Managed Configs
datamitsu can distribute configuration files from runtime-managed apps to your project via symlinks in a .datamitsu/ directory at your git root.
Apps declare what files they expose through Links:
"eslint-config": {
node: {
packageName: "@company/eslint-config",
binPath: "node_modules/.bin/eslint",
version: "1.0.0",
lockFile: "br:...",
},
links: {
"eslint-config": "dist/eslint.config.js",
},
}
After running datamitsu init, a symlink is created at .datamitsu/eslint-config pointing to the file inside the app's install directory. Your project configs can then reference it:
// eslint.config.ts
import config from "./.datamitsu/eslint-config";
export default config;
The tools.Config.linkPath() and tools.Path.forImport() JS APIs help generate correct relative paths in config files.
Tooling System
datamitsu runs fix and lint operations on your code. Tools are configured with glob patterns, scope, and commands.
Scopes
- per-file — Tool runs once per matched file (e.g.,
hadolint {file}) - per-project — Tool runs once per detected project in a monorepo (e.g.,
eslint {files}) - repository — Tool runs once from git root (e.g.,
golangci-lintwithscope: repository)
Operations
const tools = {
eslint: {
name: "ESLint",
operations: {
fix: {
app: "eslint",
args: ["--fix", "{files}"],
scope: "per-project",
globs: ["**/*.{ts,tsx,js,jsx}"],
},
lint: {
app: "eslint",
args: ["{files}"],
scope: "per-project",
globs: ["**/*.{ts,tsx,js,jsx}"],
},
},
projectTypes: ["npm-package"],
},
};
Template Placeholders
Tool arguments support placeholders that resolve at execution time:
| Placeholder | Resolves To |
|---|---|
{file} | Single file path (per-file scope) |
{files} | Separate arguments per file |
{root} | Git repository root |
{cwd} | Per-project working directory |
{toolCache} | Per-project, per-tool cache directory |
Ignore Rules
Use .datamitsuignore files to disable specific tools for matching file patterns:
vendor/**/*: golangci-lint, gofmt
*.generated.ts: eslint, prettier
Configuration Layers
datamitsu loads configuration in layers, each receiving the previous result:
Each config file must export getMinVersion() (minimum datamitsu version, checked before loading) and getConfig(prev) (receives the previous layer and returns a new config). This enables inheritance and progressive customization while ensuring version compatibility.
Your git-root config can also export getBeforeConfigs() to declare local under-layers — the config-declared equivalent of --before-config. This lets a globally installed datamitsu load a shared wrapper config without the flag. It is skipped when --before-config is passed (the flag wins). See Configuration → Declared Before-Configs.
Remote Configs
Any config can declare parent configs it inherits from:
/// <reference path=".datamitsu/datamitsu.config.d.ts" />
function getRemoteConfigs() {
return [
{
url: "https://example.com/shared-base.ts",
hash: "sha256:abcdef1234567890abcdef1234567890abcdef1234567890abcdef12345678",
},
];
}
globalThis.getRemoteConfigs = getRemoteConfigs;
Remote configs require a SHA-256 hash (mandatory) and are cached locally; cache validity is determined by hash match (no TTL).
Monorepo Support
datamitsu is designed for monorepos. It detects project boundaries by looking for markers like package.json, go.mod, Cargo.toml, and pyproject.toml.
Each project gets:
- Isolated cache at
~/.cache/datamitsu/cache/projects/{hash}/cache/{projectPath}/{toolName}/ - Scoped tool execution in the project's working directory
- Independent configuration via managed config links
When running from a subdirectory, datamitsu restricts its scope to projects within that subtree.
Next Steps
- Configuration Guide — Deep dive into config files and options
- Binary Management Guide — Managing tool binaries in detail
- Runtime Management Guide — Bun, UV, Node, JVM, and Go runtimes