DEV Community

Quinn Wang
Quinn Wang

Posted on

Your First Run Has a Tab Budget

The first fifteen minutes of a new project almost never fail because some step is slow. They fail because you keep leaving the editor — one tab for the install docs, one for the auth page, one for the cloud console, one for the ticket where someone promised the env var already exists. If you have ever finished a setup session feeling tired without being able to name a single slow command, you already know this feeling; the wall clock was fine, but your attention was chopped into pieces. So the metric I want you to instrument is not minutes per step, it is how many times you leave the editor, and the fix that matters is almost always the same: collapse the browser-shaped steps into one command you can run without thinking.

Why does timing mislead us here? A npm ci that takes ninety seconds is annoying, but it is also a single uninterrupted block you can spend reading the diff of the repo you just cloned. Five separate thirty-second detours to find out which Node version the CI uses are worse, because each one costs you the reload of the mental model you had built up. Duration is additive and predictable; interruption is multiplicative and invisible. That is why a stopwatch on your setup script tells you almost nothing useful, and why the same project can feel smooth to one developer and hostile to another who simply had more tabs open.

Build the ledger before you build the fix

The artifact here is tiny: a script that timestamps every time you step away, so the shape of the problem shows up as a list rather than a vague memory. It is not clever and it is not automated — you type one command when you leave, one command when you come back, and that manual friction is the point, because it forces you to notice the switch while it is happening.

#!/usr/bin/env bash
# tablog — record every time you leave the editor during first-run setup
# usage: ./tablog start "clone repo"   then   ./tablog mark "docs: node version"
set -euo pipefail
LOG="${TABLOG_FILE:-$HOME/.tablog.csv}"
cmd="${1:-}"; label="${2:-unlabeled}"
epoch="$(date -u +%s)"
stamp="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
case "$cmd" in
  start)  : > "$LOG"; printf '%s,%s,%s\n' "$epoch" "$stamp" "$label" >> "$LOG" ;;
  mark)   printf '%s,%s,%s\n' "$epoch" "$stamp" "$label" >> "$LOG" ;;
  report) awk -F, 'NR==1{start=$1; prev=$1; next}
                   {printf "%5ds  %s\n", $1-prev, $3; prev=$1}
                   END{printf "%5ds  total elapsed\n", prev-start}' "$LOG" ;;
  buckets) awk -F, 'NR>1{split($3,p," "); b[p[1]]++} END{for (k in b) print b[k], k}' "$LOG" ;;
  *) echo "usage: $0 {start|mark|report|buckets} [label]" >&2; exit 64 ;;
hesac
Enter fullscreen mode Exit fullscreen mode

Run ./tablog start "fresh clone" in a clean checkout of a project you have never touched, then ./tablog mark "..." each time you switch away and each time you come back. The report mode prints one line per gap so you can see the rhythm; the buckets mode groups labels by their first word, which is how you discover whether your interruptions are mostly docs, mostly auth, or mostly cloud. An illustrative session, not a real one — yours will differ — might read docs 6, auth 3, cloud 4, and that distribution is the whole diagnosis. Six trips to the docs is not a documentation problem; it is a repository problem, because the answers should have been in the repo.

The one fix: move the browser steps into the repo

Here is the change that actually moved the needle for the pattern above, and it is embarrassingly small. Whatever you had to look up in a browser during the first run goes into a single checked-in file, and every step it describes becomes a target in one entry point, so the answer to "how do I start this?" is a command rather than a search.

.PHONY: first-run
first-run: env-check deps migrate smoke
    @echo "first run complete — you never left this terminal"

env-check:
    @test -f .env || cp .env.example .env
    @test -n "$$DATABASE_URL" || { echo "DATABASE_URL is empty; see .first-run/README.md"; exit 1; }

deps:
    npm ci --no-audit --no-fund

migrate:
    npm run migrate

smoke:
    npm run test:smoke
Enter fullscreen mode Exit fullscreen mode

Notice what this does not do: it does not make anything faster. npm ci still takes as long as it takes, and the migration still has to run. What it removes is the decision layer — the moment where you wonder whether you should run migrations before or after seeding, and open a tab to check. Three or four of those decisions are normal in a new repo; ten of them is a tax you are paying for someone else's undocumented assumptions. The .first-run/README.md next to the Makefile is where the pinned versions, the required env vars, and the "yes, the smoke test fails the first time, run it twice" note live, so the repo answers before the browser does.

Where a hosted dev environment fits

One class of interruption is different from the rest: the toolchain itself. Installing a language runtime, a database, and a compiler on a fresh laptop is where the tab count explodes, and it is also the part with the least to do with your actual code. This is the point at which a hosted option is worth evaluating — I have been looking at MonkeyCode, which the operator describes as an open-source project offering free model access and a free server option, and the operator currently states that the free allowance is 10 million tokens. Verify the current numbers and terms on the project page before you plan around them, because allowances and server terms in this space change on a schedule nobody announces.

Disclosure: This article was prepared as part of MonkeyCode's product outreach.

The reason it belongs in a tab-count article rather than a model-quality article is narrow and honest: two of the biggest interruption sources in a first run are "install and configure a runtime" and "go get an API key and add a payment method". A hosted server removes the first from your laptop, and free model access removes the second from your afternoon. Neither makes your code better, and neither is a reason to move a regulated workload onto someone else's machine.

Situation Local toolchain Hosted free server
Trying a repo for the first time Fine, but high tab count Strong fit: one fewer install
Data you cannot ship off-machine Required Do not use
Pinned, reproducible CI image Required Not a substitute
Offline or flaky-network work Required Poor fit
Prototype you will delete Friday Overkill Strong fit

What this method cannot tell you

The ledger is manual, so it measures what you remember to log, and a developer who forgets to log is exactly the developer having the worst time. It also says nothing about severity: a single twenty-minute detour to fix a broken certificate is worse than eight quick doc checks, and the count alone will not show you that. And if your first run is already a single make first-run that takes four minutes, stop reading — instrumenting that is pure overhead, and the honest answer is that someone already did this work for you.

So try it on the next repo you clone. Start the log, work for fifteen minutes without pretending, and look at the labels instead of the durations. If the biggest bucket is docs, your fix is a file in the repo; if it is auth or cloud, your fix might be a hosted environment; if it is install, your fix is a container or a server, not more patience. Either way, the tab count tells you which one to fix first, and that beats guessing.

Top comments (0)