How Collie works out how to start a repo
18 October 2026
Every project starts in its own way. One needs npm run dev, another bundle exec jekyll serve, and another a script someone wrote years ago. The goal is for Collie to start any of them without being told, by following a short list of checks in a fixed order: look here first, then here, and if you find this, run that.
The order Collie checks
The first match wins.
- Your own rules. If you’ve told Collie how to run a repo, that always comes first.
- A launch script. If the repo has
scripts/launch.sh, Collie runs it. - A Procfile. If there’s a
web:line, Collie runs that, on a free port. - package.json scripts. Collie looks for a
dev,start,serveorpreviewscript, in that order. It picks npm, yarn, pnpm or bun from the lockfile, and installs first if it needs to. - Docker Compose, then a Makefile. A Compose file means
docker compose up. A Makefile with aruntarget meansmake run. - A dev container. If the dev container’s start command also works on your Mac, such as
npm run dev, Collie runs it there, and checks the first port it forwards. Setup steps such as installs are left out. - Other well-known setups. Jekyll, Rails, Swift packages, Deno, Rust, Go, Hugo, Gradle and Python each have one clear way to start.
- Clues in the repo. The project’s own launcher, if it really starts something that keeps running. Then the first simple, safe run command in the README. Then a Dockerfile that says which port it uses. Then, if there’s an
index.html, Collie serves the folder on a free local port. - Ask you. If nothing matches, the repo goes under Can’t start yet, with a plain reason, for example that it’s a Figma plugin, or that it needs a tool you haven’t installed. You type the command once, and Collie remembers it.
There’s no single standard
There’s no single standard for how a repo runs. But plenty of projects already say how, in one file or another. Where a project declares it (a Procfile, package.json, Docker Compose, a Makefile or a dev container), Collie simply reads that. The guessing only kicks in when nothing declares it, much like buildpacks do for deploys.
Here’s what each of the common ones covers:
- Procfile: from Heroku. One line per process, for example
web: npm start. - package.json scripts: JavaScript’s de facto convention. Only
startandtesthave a built-in meaning. - Docker Compose: an open spec for running services in containers.
- Dev containers: an open spec from VS Code and GitHub Codespaces. It describes the dev environment, its setup and start commands, and which ports to forward.
- Make, Just, Task and mise tasks: task runners that give you named commands, with no agreed name for ‘run’.
- Earthly: containerised builds, mostly for CI.
- asdf and mise tool versions: which versions of tools to use, not what to run.
- Nix flakes: reproducible dev shells, and a
nix runcommand. - Gitpod config, devenv and process-compose: each declares start commands for its own tool.
Just and mise files are the likely next checks.
When two standards disagree
Some repos declare more than one. Collie picks the one meant for working locally:
- Procfile and package.json. The Procfile wins, because it names the process outright. But if it only runs a package.json script, Collie uses package.json’s
devscript instead. And if the Procfile is clearly for production, for example gunicorn,NODE_ENV=productionor arelease:line, any dev command wins. - A Compose file that only runs databases. Collie runs the app’s own command, not Compose.
- A Makefile that just calls another command. If
make runonly runs, say,npm run dev, Collie runs that directly. If it only opens an app, there’s nothing to keep running, so Collie moves on. - A dev container. It never overrides one of the others. If its start command only works inside the container, Collie skips it and says so.
- A Dockerfile on its own. Often it’s only for deploys, so Collie uses it near the end, and only if Docker is installed and the Dockerfile says which port it uses.
- A missing tool. If the winner needs something your Mac doesn’t have, Collie tries the next check, and tells you why if nothing’s left.
Getting better over time
When Collie gets a repo wrong, the fix goes into the shared checks, so the next similar repo just works, rather than being a one-off rule for that repo. The list stays short, and every check earns its place.