How I Learn by Doing: A Repeatable Mini Project Loop
I learn faster by shipping small, real things than by planning large, imaginary ones. This post describes the actual loop I use when I want to understand a tool or idea: I build a tiny working demo, put it somewhere public, then write down exactly what broke and what I changed. Nothing here is aspirational. Every step ends in a file, a command, or a URL you can verify.
The point of this loop is not productivity theater. The point is to force contact with real environments: the browser, the build output, the deployment host, and the mistakes that only appear once something is live.
The shape of the loop
A usable learning loop has three visible artifacts. There is a local project that runs. There is a public link that proves it runs outside your machine. There is a short written note that captures what actually went wrong and what you fixed. If any of those are missing, the loop is not complete and the learning stays fuzzy.
This post walks through a concrete example using a single static HTML page. The example is intentionally simple because the mechanics of building, verifying, and deploying are the part that matters. The same loop applies to larger stacks later.
A real starting point: one tiny demo
Start with an empty folder and create the smallest possible project. No frameworks, no scaffolding tools, no generators. Just a file that does one thing and can be opened in a browser.
mkdir mini-democd mini-democat > index.html <<'EOF'<!doctype html><html lang="en"><head><meta charset="utf-8" /><title>Mini Demo</title></head><body><h1>Click the box</h1><div id="box" style="width:100px;height:100px;background:#4f46e5;cursor:pointer"></div><p id="status"></p><script>const box = document.getElementById("box");const status = document.getElementById("status");box.addEventListener("click", () => {status.textContent = "Box clicked at " + new Date().toLocaleTimeString();});</script></body></html>EOF
Open index.html in a browser and click the square. If the timestamp appears, the demo is real. This is the first important point: the project exists outside your head and outside a tutorial. It runs.
Local verification before anything else
Before thinking about deployment, confirm the demo behaves correctly in a clean browser session. Reload the page. Click again. Confirm the timestamp updates every time. If this fails locally, deploying it only publishes a broken artifact. Fix local behavior first, always.
This step sounds obvious, but it is where most abandoned projects die. Local verification is the first filter that separates "I thought about building" from "I built something that executes."
Putting the demo under version control
Now make the demo something you can actually share. Initialize a git repository and commit the file.
git initgit branch -M maingit add index.htmlgit commit -m "Add mini demo"
At this point you have a reproducible artifact. Anyone can clone the repo and open the same file. That reproducibility is part of the learning process. If you cannot reproduce your own demo later, the learning is lost.
Deploying the demo to a real URL
A demo that only runs on your machine is still half-finished. The moment you put it on a public URL, you force yourself to confront file paths, hosting behavior, and browser caching. This example uses GitHub Pages through GitHub Actions because it removes manual steps and produces a visible deployment log.
Create the workflow file:
.github/workflows/pages.yml
name: Deploy Pageson:push:branches: ["main"]permissions:contents: readpages: writeid-token: writeconcurrency:group: "pages"cancel-in-progress: truejobs:deploy:environment:name: github-pagesurl: ${{ steps.deployment.outputs.page_url }}runs-on: ubuntu-lateststeps:- name: Checkoutuses: actions/checkout@v4- name: Setup Pagesuses: actions/configure-pages@v5- name: Upload artifactuses: actions/upload-pages-artifact@v3with:path: .- name: Deployid: deploymentuses: actions/deploy-pages@v4
This workflow is mechanical. It checks out your repository, tells GitHub this job is a Pages deployment, uploads the current folder as the site artifact, and publishes it. There is no build step because this demo is plain HTML. For larger projects, the only change is adding a build command before the upload.
Push the repository to GitHub:
git remote add origin https://github.com/<yourname>/mini-demo.gitgit push -u origin main
When the push completes, open the Actions tab in your repo. You will see the workflow run. When it finishes, GitHub shows the live Pages URL. Open that URL and click the square. If the timestamp updates, your demo is now running on infrastructure you do not control. That is the second important point: your code survived a clean environment and a real host.
Proving the deploy actually updated
To avoid fooling yourself with cached pages, reload the URL with a hard refresh. Click the square again. The time should change. If the page does not update, check the Actions run logs. They will show whether a new deployment actually happened. This is where you learn to trust logs over assumptions.
Writing down the lesson
After the demo is live, write one short note about what actually happened. Create a file named lesson.md and write three sentences.
cat > lesson.md <<'EOF'The demo broke the first time because I forgot to enable Pages → Source → GitHub Actions.After fixing that, the workflow deployed correctly and returned a live URL.Next time I will always check Pages settings before debugging YAML.EOF
This is not documentation for others. This is a memory aid for you. When you repeat this loop with a different tool later, these small notes prevent you from relearning the same mistakes from scratch.
Why this loop works
This process forces three real interactions: writing code that runs, deploying to a host you do not control, and reading logs when something fails. Those interactions are where understanding forms. Reading articles or watching videos can introduce concepts, but shipping even a tiny demo is what makes them stick.
Over time the demos get larger, the stacks change, and the deployment targets evolve. The loop stays the same: build something small, verify locally, deploy publicly, record what actually broke. That repetition is the real curriculum.
Closing
If you have a local demo that runs, a public URL that proves it, and a short note that captures what went wrong, you have learned something concrete. Everything else is just preparation for that moment.