Skip to main content
meow executes a single ES module to completion through V8. It runs .js, .mjs, .cjs, and TypeScript (.ts, .mts, .cts, .tsx) directly — no build step, no ts-node, no loader flags.

meow run

meow run main.ts
meow run ./scripts/seed.ts
meow run dev            # runs the "dev" package.json script
meow run <target> does one of two things, in this order:
  1. If <target> matches a script in your package.json, it runs that script (with pre/post lifecycle hooks — see below).
  2. Otherwise it treats <target> as a file path, resolves it, and drives that module through the runtime.

Forwarding arguments

Pass arguments to your program after --:
meow run app.ts -- --port 8080 --verbose
meow run dev -- --watch
Everything after -- is forwarded verbatim as the program’s argv.

meow dev

meow dev is shorthand for meow run dev. It prints a cold-start banner with your project mode and the time-to-first-byte, then runs the dev script:
meow dev
meow dev -- --host 0.0.0.0

meow task

meow task <name> runs a package.json script by name, using the same resolution as meow run. It’s the explicit form when a script name might collide with a file path.
meow task build

The omni-router

meow leans on muscle memory. When the first argument isn’t a known subcommand, the omni-router infers your intent so you rarely need to type run or x:
You typeBecomesRule
meow buildmeow run builda standard script name (build, start, dev, lint, test, preview, serve, …)
meow ./app.tsmeow run ./app.tsa path, or a .js/.ts/.json/... file
meow /abs/server.jsmeow run /abs/server.jsan absolute path
meow create-vite appmeow x create-vite appunknown name → ephemeral package
meow -e "..."eval mode-e/--eval/-p/--print
It also smooths over cross-ecosystem habits:
  • Competitor flags are stripped before parsing: --shell <value>, --silent, --no-warnings, and redundant inner package-manager calls (bun run bun buildbun run build).
  • Deno-style run flags are stripped: -A, --allow-all, --unstable, --unstable-* are accepted and ignored, so scripts copied from Deno don’t crash.
Mistype a command and meow suggests the nearest match: Unknown command 'installc'. Did you mean 'install'?

package.json scripts

When you run a script, meow plans how to execute it intelligently rather than always spawning a shell:
1

Native fast path

If the script is a simple command whose target resolves to a local file or a dependency’s bin (e.g. node ./build.cjs, tsc, vite), meow runs it directly in the runtime — no shell process.
2

Shell fallback

If the script uses shell features — pipes, &&, redirects, globs, subshells — meow runs it through sh -c (or cmd /C on Windows) so it behaves exactly as written.

Lifecycle hooks

pre<name> and post<name> scripts run automatically around <name>, npm-style. A non-zero exit from a pre hook stops the chain.
package.json
{
  "scripts": {
    "prebuild": "meow run clean.ts",
    "build": "meow run build.ts",
    "postbuild": "meow run report.ts"
  }
}
meow also sets the familiar lifecycle environment variables for scripts: INIT_CWD, npm_lifecycle_event, npm_lifecycle_script, and npm_package_json.

Eval & print

Run inline source without a file:
meow -e "console.log(1 + 1)"          # eval
meow -p "Math.max(3, 7)"              # eval + print the result
-p / --print wraps your expression in console.log(...). (These map to the internal node-eval mode; an interactive REPL is not provided.)

Exit codes

meow propagates your program’s exit code to the shell. process.exit(n) and a natural completion both surface correctly (codes are taken modulo 256, like a normal process):
process.exit(2);   // node-compat
meow run app.ts; echo $?   # → 2

V8 tuning

Two escape hatches pass straight through to the engine:
meow run app.ts --max-old-space-size=4096   # heap limit in MiB (like Node)
meow run app.ts --v8-flags=--max-semi-space-size=64,--trace-gc
--max-old-space-size is also read from NODE_OPTIONS if present, for drop-in compatibility.

Next: TypeScript support

How meow runs .ts directly, and the one place it diverges from Node’s ESM resolution.