Build a TIL System That Actually Works
Table of content
A TIL (Today I Learned) is a short note about something you just figured out. Not a tutorial. Not an essay. Just your notes, captured before you forget.
Josh Branchaud has over 2,200 TILs across 14 years. Simon Willison has 350+ TILs and says most took less than 10 minutes to write. The format works because it removes every excuse not to write.
Why TILs Beat Traditional Notes
| Traditional Notes | TILs |
|---|---|
| “I’ll write this up later” | Write it now, 5 minutes |
| Private, unsearchable | Public, Google-indexed |
| Organized by project | Organized by topic |
| Pressure to be thorough | Permission to be quick |
The mental shift: you’re not writing documentation. You’re leaving breadcrumbs for yourself.
As Simon Willison puts it: “Call it a TIL, and you’re not promising anyone a revelation or an in-depth tutorial. You’re saying ‘I just figured this out: here are my notes, you may find them useful too.’”
The GitHub Repo Setup
The simplest TIL system is a GitHub repo with topic folders:
mkdir til && cd til
git init
# Create your first topic folder
mkdir git
echo "# TIL
Today I Learned, in short notes.
## Categories
- [Git](git/)
" > README.md
Write your first TIL:
cat > git/undo-last-commit.md << 'EOF'
# Undo the Last Commit Without Losing Changes
Keep your changes staged but remove the commit:
```bash
git reset --soft HEAD~1
Keep your changes but unstaged:
git reset HEAD~1
Nuke everything:
git reset --hard HEAD~1
Found this when I accidentally committed to main instead of a feature branch. EOF
Commit and push:
```bash
git add .
git commit -m "First TIL: undo git commits"
git remote add origin git@github.com:YOUR_USERNAME/til.git
git push -u origin main
Done. You have a TIL system.
The Auto-Updating README
Josh Branchaud’s repo auto-generates a README with categories and counts. Here’s the minimal version:
cat > generate-readme.sh << 'EOF'
#!/bin/bash
echo "# TIL"
echo ""
echo "$(find . -name '*.md' ! -name 'README.md' | wc -l | tr -d ' ') TILs so far."
echo ""
echo "## Categories"
echo ""
for dir in */; do
if [ -d "$dir" ]; then
name=${dir%/}
count=$(find "$dir" -name '*.md' | wc -l | tr -d ' ')
echo "### $name ($count)"
echo ""
for file in "$dir"*.md; do
if [ -f "$file" ]; then
title=$(head -1 "$file" | sed 's/^# //')
echo "- [$title]($file)"
fi
done
echo ""
fi
done
EOF
chmod +x generate-readme.sh
Run it before each commit or set up a pre-commit hook.
TIL Templates
Keep a template so you can start fast:
# [Title: What You Learned]
[1-3 sentences explaining the context]
```[language]
# The code or command that solved it
[Optional: gotcha or edge case]
[Optional: link to docs or source]
Real example structure:
```markdown
# Use jq to Extract Nested JSON Keys
Needed to pull all "name" fields from a nested API response.
```bash
cat response.json | jq '.. | .name? // empty'
The .. recursively descends. The // empty suppresses nulls.
Docs: https://stedolan.github.io/jq/manual/
## Topic Organization
Don't overthink categories. Start with the tool or language name:
til/ ├── bash/ ├── docker/ ├── git/ ├── javascript/ ├── postgres/ ├── python/ └── vim/
Create new folders as needed. Merging later is easy. Paralysis now is expensive.
## Publishing Options
| Method | Effort | Result |
|--------|--------|--------|
| GitHub repo | Zero | Markdown rendered on GitHub |
| GitHub Pages + Jekyll | Low | Static site with search |
| Custom site | Medium | Full control over design |
| [Datasette](https://datasette.io/) | Low | SQL-searchable database |
Simon Willison uses [Datasette Lite](https://lite.datasette.io/) to make his TILs searchable. The repo is the source of truth; the site is just a view.
For most people, a GitHub repo is enough. Don't let publishing friction stop you from writing.
## The 10-Minute Rule
If something took you more than 5 minutes to figure out, it's worth a TIL. The threshold isn't "is this interesting to others?" The threshold is "will I forget this?"
Write for yourself from 3 months ago. That's the only audience that matters.
As [swyx](/concepts/learning-in-public/) says: "Make the thing you wish you had found when you were learning."
## What You Can Steal
**Josh Branchaud's setup**: [github.com/jbranchaud/til](https://github.com/jbranchaud/til). 14k stars. Simple folder structure, auto-generated README, MIT licensed.
**Simon Willison's TIL site**: [til.simonwillison.net](https://til.simonwillison.net/). Uses GitHub repo + Datasette for publishing. RSS feed included.
**Template repo**: Fork [simonw/til](https://github.com/simonw/til) for a GitHub Actions workflow that auto-publishes to a static site.
## Common Mistakes
**Waiting for "interesting" topics**. You're not writing blog posts. Write the boring stuff.
**Over-organizing before writing**. Create folders as you need them. One TIL in the wrong folder is fine.
**Making it too long**. If you're past 200 words, you're writing a tutorial. Split it or accept the scope change.
**Not writing context**. "Use `--force`" means nothing in 6 months. Add why you needed it.
## Connecting to Your Second Brain
TILs feed into larger knowledge systems. A TIL about a jq trick today becomes a reference when you write a data processing guide next month.
The workflow:
1. Write TIL when you learn something
2. Tag or organize by topic
3. Reference TILs in longer content
4. Let patterns emerge
This is [learning in public](/concepts/learning-in-public/) at its most practical: small deposits that compound.
For deeper organization, see [digital gardens](/concepts/digital-gardens/), where TILs become nodes in a knowledge graph.
---
**Next:** [LLM Logging](/guides/llm-logging/) for capturing what you learn from AI interactions.
Get updates
New guides, workflows, and AI patterns. No spam.
Thank you! You're on the list.