Skip to main content
meow is designed to be a drop-in for most Node.js projects. It reads your existing package.json, resolves the same npm packages, and runs the same frameworks. This page maps what you already type onto meow, then calls out the few things that are deliberately different.

Command cheat sheet

The omni-router

meow infers intent from bare invocations, so most habits keep working without the run verb. When the first argument isn’t a known command, meow routes it: It also strips competitor-specific flags (--shell, --silent, --no-warnings) and Deno-style run flags (-A, --allow-all, --unstable-*) so scripts copied from other ecosystems don’t crash the parser. Full details in Running code.

The node shim

When meow runs your scripts, it puts shims for node, npm, pnpm, yarn, bun, npx, pnpx, and bunx first on PATH. So when a framework (Next.js, Vite, Jest workers) shells out to node, it transparently re-enters meow. You don’t have to change how tools invoke each other.
Need a real node for one command? Set MEOW_NO_SHIM=1 and the shim execs the system binary instead.

File-for-file

meow can also write a tiny package-lock.json compatibility marker so framework detectors that look for it still light up — meow install --compat-lockfile. Your meow.lock.jsonl stays the source of truth.

What’s genuinely different

These are intentional. Knowing them up front saves surprises.
A fresh meow init project runs in strict-web mode: the clock is frozen, Math.random/crypto.getRandomValues are seeded, and the timezone is pinned to UTC. Code that reads Date.now() expecting real wall-clock time will see a fixed value until you grant the real clock with --allow-clock (or switch to node-compat). This is what makes tests and CI reproducible. See Determinism.
In strict-web, environment variables are invisible and node:fs/node:process throw ERR_STRICT_WEB_WITHDRAWN. You opt back in with --allow-env, --allow-clock, --allow-random, or --trust. In node-compat mode (use it for Node apps and frameworks) the full host surface is available like Node. See Permissions.
"zod": "3.23.8" means exactly 3.23.8. "3.23" means >=3.23.0 <3.24.0, "3" means >=3.0.0 <4.0.0. ^, ~, ||, and hyphen ranges all behave the npm way. npm aliases (npm:pkg@range) and dist-tags (latest) are supported.
There is no .eslintcache, no per-tool daemon, no separate tsc --watch server. meow holds one syntax graph in memory for the lifetime of a command and feeds every tool from it.

A typical migration

1

Drop meow into the repo

Keep your package.json. Add a meow.config.json:
meow.config.json
node-compat is the safe starting point for an existing Node app — full Node surface, host access, real clock.
2

Install

This resolves your existing dependencies, writes meow.lock.jsonl, and materializes node_modules.
3

Generate editor shims

Writes .meow/tsconfig.json and a root tsconfig.json shim so your editor and meow check agree on the type surface.
4

Run your scripts

Next: the two runtime modes

The single most important concept when moving a project to meow.