Your first hour: setup that pays off
The most productive hour in a new project is spent making it runnable, testable and reversible — before you write anything clever.
- You can set up a project so anyone (including you in a month) can run it in one command.
- You know the eight things every repository should have on day one, and why each one is cheaper now than later.
The classic failure isn't a hard bug. It's the project that only runs on one laptop, because the setup lived in someone's head: three global installs, a config file nobody committed, a database seeded by hand, and a README that says "install dependencies". A week later it takes two days to onboard a single person.
The fix is a single rule that everything else follows: one command to run it, one command to test it, from a clean checkout. If that's true, a new machine is a five-minute problem instead of a two-day one.
my-app/
├─ README.md # 3 lines: what it is, how to run it, how to test it
├─ .nvmrc / .tool-versions # pin the runtime — "it works on 22.x" is not a version
├─ package.json # scripts: dev, test, lint, format (any language has equivalents)
├─ lockfile # committed, always — portable.json / poetry.lock / go.sum
├─ src/ # application code
├─ tests/ # tests next to the code they test is also fine
├─ .env.example # every variable required, with fake values, committed
└─ .github/workflows/ # CI: install, lint, test on every push
2.1The eight things
| Item | Why it matters | Check |
|---|---|---|
| Pinned runtime | Different versions produce different bugs | A new machine gets the same version automatically |
| One-command run | Removes the "how do I start this" tax | make dev / npm run dev works from a clean clone |
| One-command test | Makes checking cheaper than guessing | Full suite under a couple of minutes at the start |
| Formatter | Ends style arguments permanently | Runs on save or in CI; nobody discusses braces again |
| Linter / type check | Catches whole classes of bug before runtime | Fails CI on errors, not on taste |
| Git from the first line | Every experiment becomes reversible | First commit exists before the first "big" feature |
| README with commands | It is the only documentation everyone reads | Three sections, copy-pasteable |
| CI pipeline | Proves it works somewhere that isn't your laptop | Green on a fresh clone, in a container |
Six or more is a healthy start. Fewer than four and your next week will be spent on setup archaeology instead of building.
Take your current project (or an empty folder). Add: a pinned runtime file, a `dev` script, a `test` script, a formatter, and a README with three sections. Delete the global installs from your notes and put the versions in the repo. Then clone it into a temp directory and make it run — that's the real test.
Anything you installed globally, configured by hand, or fixed by deleting a folder is a bug in the project, not a quirk of your machine. Write it into the repo or automate it. If a fresh clone cannot run it, it does not run.
2.2Where setup actually goes wrong
The eight items are not housekeeping. Each one exists because a specific failure is otherwise guaranteed, and the failure always arrives at the worst possible moment.
| Failure | The symptom | The item that prevents it |
|---|---|---|
| The invisible environment | It works on two machines and fails on the third, usually a colleague's, usually the day of a demo | A pinned runtime plus one command that installs everything |
| The missing entry point | Nobody can say how to run the tests; every new person asks in chat and gets a different answer | A make test (or equivalent) that is the only documented way |
| The unpinned dependency | Nothing changed, but a fresh install broke the build at 9am | A lockfile, committed, plus a CI run that installs from it |
All three share a shape: they are cheap to prevent at the start and expensive to retrofit, because the fix requires changing something everybody already relies on. That is the whole argument for the first hour — not tidiness, but avoiding a class of problem that only appears when you have the least time to solve it.
You have one hour before starting a new project. What buys the most later?
60-second recap
- One command to run, one command to test, from a clean checkout. Everything else follows from that.
- Pin the runtime, commit the lockfile, document the variables. "Works on my machine" is a defect.
- Formatter and linter end arguments about style and catch bugs before runtime.
- Set this up on day one; it is a five-minute task now and a lost week later.