The Blog
New blog post every Wednesday! I write regularly about technology, communities and life around me. I aim to publish a new blog post each Wednesday. If you wish to get notified when new posts arrive, I have a RSS feed you can subscribe to.
I have blog stats page if you like that sort of thing!
I've also visited a few podcasts which you can find on my speaking page.
For my longer pieces, check out Humane Tech Guides.
In addition to these posts, I wrote a blog in Finnish about my year in San Francisco back in 2014. It lives on it's own page at https://hamatti.org/unelma.
2024
December
- Struggles with believing in myself11th
- Three is a pattern4th
- Advent of Code 2024: How to write notes as a developer2nd
- Syntax Error #17: Debug December1st
November
- I like the person I am when I travel27th
- Search your notes first20th
- End of year self-reflection with Year Compass16th
- Impact.13th
- How I teach Eleventy from scratch6th
- The Non-Prime Regex is in the cross-section of two of my interests4th
- Notion is adding an offline mode2nd
October
- I built a custom RSS hydrator for better GitHub and Youtube feeds30th
- My on the go solution with iPad and Raspberry Pi23rd
- How I take work notes as a developer16th
- Multilingualism in a global web9th
- 12th anniversary of hamatti.org2nd
September
- Automate filling a form with a bookmarklet26th
- Auto Note Mover and templates make a nice duo in Obsidian21st
- Do one thing well and communicate with others18th
- What to do first with a legacy project?11th
- Blindspot is a great series that suffers from a pacing issue7th
- What’s up with blogging challenges?4th
August
- Blaugust 2024 retrospective31st
- Book recommendation: Fluent Python (2nd Edition)30th
- What’s coming to Python in 3.13 and 3.1429th
- Couple of great Python podcasts28th
- Quick prototyping with sqlite327th
- Parse command line arguments with argparse26th
- Pretty print and validate JSON on command line with json.tool25th
- Test your codebase with unittest24th
- Branch out with pattern matching23rd
- Serve local HTML and CSS files with http.server22nd
- Bring your custom toolkit to REPL sessions21st
- Keep track of happenings with logging20th
- Memoize with functools.cache19th
- map and filter with list comprehensions18th
- Combine iterables with zip17th
- Random number chosen by fair dice roll16th
- Write more pythonic code with context managers15th
- Combinatoric iterators from itertools14th
- Rituals build community camaraderie13th
- A bunch of small game reviews: Shogun Showdown, Into the Breach and Fly Corp12th
- Data classes in Python with dataclasses11th
- Rotating turn order with deque10th
- Debug with pdb and breakpoint9th
- Document intended usage through tests with doctest8th
- Improved print readability with pprint7th
- help() me Obi-Wan Kenobi, you’re my only hope6th
- Count ‘em5th
- Improve your code with namedtuples4th
- Reading and writing CSV with Python3rd
- Parsing nginx server logs with regular expressions2nd
- Blaugust 2024: Batteries included1st
July
- I have a super power: suspension of disbelief31st
- My desk setup, 2024 edition27th
- Art forgery, LLMs and why it feels a bit off24th
- Notes are a tool for …22nd
- Home-cooked, situated software20th
- Advocate for your colleagues17th
- Syntax Error #16: Crossroads and recap17th
- Blaugust starts August 1st15th
- Future Frontend 2024 Recap13th
- Different ways I start writing new code10th
- I prefer discussion in open web8th
- First impressions on Seasons6th
- Scoping the /now3rd
- A peek into my pocket notebook1st
June
- Why a personal site rather than social media presence?30th
- JSON Schema: require properties based on values of other properties29th
- Website self-sustenance checkup 26th
- Short history of my blogging journey22nd
- Tomorrow is Volunteer Responsibility Amnesty Day19th
- Syntax Error #15: Walking the walk17th
- Multi-select, filterable command-line interface with inquirer15th
- Crafting tabletop games12th
- Webmention bookmarklet10th
- What does it feel like to read RSS feeds?8th
- Make ripples through time and space by writing5th
- IndieWeb Carnival May Round-up post: Creative Environments1st
May
- Third places and meetups29th
- A lot of advice is a product of survivorship bias25th
- Inflexible systems grind my gears22nd
- Reminder: IndieWeb Carnival May is still running20th
- Syntax Error #14: I don't know17th
- Recap of 11ty International Symposium on Making Web Sites Real Good 15th
- Two small hockey web projects12th
- But someone already wrote about it11th
- The nook of creativity8th
- The importance of momentum in writing4th
- Indie Web Carnival May 2024: Creative environments1st
April
- The Future of Jamstack panel discussion24th
- Good enough as a power for good17th
- index.md is a valid Eleventy project13th
- Prepare, Perform, Ponder10th
- I can :has() cheeseburger8th
- Markdown - the trade-offs of simplicity6th
- Sharing podcast episodes is weird3rd
- Documentation pages from dotfiles with config-renderer1st
March
- Full-text RSS feed is an offline-friendly act30th
- Chance of serendipity27th
- Traveling through time25th
- I had a chat about personal web at The Future of Jamstack24th
- I completed #100DaysToOffload23rd
- Recent evolution of my note taking systems20th
- My most used bookmarklets18th
- Syntax Error #13: Playgrounds17th
- On content creation and personal web16th
- Search directly on a website with Firefox bookmark keywords13th
- Thoughts on accessibility in personal web11th
- Chesterton’s Fence and tech documentation6th
- Display full URL after a link when a page is printed4th
February
- Search, Webmentions and microformats28th
- THE Eleventy Meetup Feb 20th26th
- Pull request is my proposal for changes24th
- Talk ideas for new and experienced speakers21st
- Thank you, Startuplifers19th
- Syntax Error #12: Browser Extension Debugging17th
- We organized a Code in the Dark event16th
- Stickers tell stories14th
- Public notes12th
- Anonymous, asynchronous friendships10th
- Highlight Mastodon posts by hashtag with Stylus and :has7th
- I like to glue things together3rd
January
- We have a great developer community scene in Turku31st
- Please, don’t force me to log in27th
- Python Bytes featured Syntax Error25th
- Community websites with Eleventy24th
- The Lazarus Project (review)22nd
- A few core memories20th
- Syntax Error #11: Debugging Python17th
- I wish Python had Integer.times17th
- Debugging Python13th
- Join us at Future Frontend 202410th
- Write it anyway8th
- Workaround for Notion’s lack of heading levels6th
- Advent of Code 2023 retrospective3rd
2023
December
- Year in Review 202327th
- Merry Christmas!20th
- Syntax Error #10: Debugging knowledge base17th
- Two months with Obsidian13th
- We’re building community for Python developers6th
November
- Advent of Code is just around the corner29th
- Three travel essentials25th
- People and Blogs newsletter22nd
- Syntax Error #9: Distilling the minimum example17th
- What's in the name? The story behind my domain15th
- Done is the engine of more8th
- Use SQL to query your CSV files4th
- Learning Rust #10: Added new feature with a HashMap1st
October
- Showing most popular posts with Netlify Analytics28th
- Priority order when you start blogging25th
- Great details on conference badges18th
- Syntax Error #8: What we can learn from hardware debugging?17th
- I got to show you this14th
- Handling JSON on command line11th
- Document your secrets4th
September
- Traveling Europe on land: Turku to Prague27th
- How you can make conferences better20th
- Syntax Error #717th
- Pull requests are great13th
- My iterative approach to software development6th
August
- Blaugust 2023: Lessons Learned31st
- Use pangrams to avoid mistakes in conference badge prints30th
- My First 100K29th
- Custom cookie consent for video embeds28th
- Compressing overlapping strings in Python27th
- Where do my links live?26th
- 6 months of recovery, how is life?25th
- Building Dark Mode for hamatti.org24th
- Let’s talk about Steam Deck23rd
- Website rewrite and switching to Notion as CMS22nd
- Stardew Valley Mods I use21st
- Youtubers I watch20th
- Bloggers I read: Saturday19th
- Bloggers I read: Friday18th
- Bloggers I read: Thursday17th
- Syntax Error #6: Debugging CSS17th
- Bloggers I read: Wednesday16th
- Bloggers I read: Tuesday15th
- Pokemon tools updated for Obisidian Flames14th
- Desert Island Discs13th
- Future Frontend 2023 Recap12th
- Projects I'm proud of: Teaching programming11th
- Projects I'm proud of: Potluck10th
- Projects I'm proud of: Newsletters9th
- Projects I'm proud of: Turku ❤️ Frontend8th
- Projects I'm proud of: Boost Turku & Startup Journey7th
- Tools don't matter - until they do6th
- What makes a blog post a blog post?5th
- Where to publish your blog?4th
- Build an idea bank and never run out of blog ideas3rd
- A bunch more of small game reviews: Dredge, Dishonored, Farm Keeper2nd
- Blaugust 2023, here we come1st
July
- Blog comments via Mastodon26th
- What tech docs can learn from video game tutorials?19th
- Syntax Error #5: Python breakpoints17th
- Hey dev student: you should study creative writing12th
June
- Give your commands consistent names21st
- Document outdated components14th
- How to network while being beneficial to oneself professionally?7th
May
- Writing documentation is a great tool to improve software quality31st
- I found new great games24th
- Syntax Error #4: Refreshing wrong window17th
- I got my hands on the finished product (Potluck)17th
- In a beautiful world, APIs would be open3rd
April
- How to document a workaround?26th
- A look at my on-going projects19th
- Syntax Error #3: Who let the ducks out?17th
- How to sort a Pokemon deck list?12th
- Potluck #3: My workflow5th
March
- Organizing a mess with cherry-picking29th
- A quick life update22nd
- Syntax Error #2: print it like a boss17th
- A bunch of small game reviews: Village Rails, Skulls of Sedlec, Barotrauma15th
- I combat impostor syndrome with building in public10th
- Potluck #2: The Deck1st
February
- Syntax Error #1: Welcome17th
- The imperfect mess of note taking15th
- In defense of Quote Toots8th
- Potluck #1: Research and Design1st
January
- Guide to landing your first dev job25th
- My Pokemon apps updated for Crown Zenith20th
- I'm leaving Mozilla18th
- Me and the elves - Advent of Code 2022 retrospective11th
- Introducing: Syntax Error4th
2022
December
- Year in Review 202228th
- Merry Christmas21st
- 7 years of Turku ❤️ Frontend (via Medium.com)15th
- DevRelCon Prague 2022 Recap14th
- Mastodon redirect with your domain in Netlify7th
- Verifying identity online7th
November
- Python prep for Advent of Code 202230th
- steamos-readonly25th
- New Firefox extension to help Pokemon TCG players23rd
- My overengineered tooling for Pokemon TCG Card Viewer extension16th
- How to wait for user input from Firefox extension page before continuing9th
- I joined Mastodon5th
October
- Find assigned tasks from Google Drive26th
- Upcoming live stream: first look at Rocket Oct 22nd20th
- Ad-Filtering Dev Summit 2022 Recap19th
- React Finland 2022 Recap12th
- Set up a dashboard using Google Slides4th
September
- kittens-everywhere – how to build a browser extension28th
- Traveling in connected, digitalized world21st
- Why I do what I do?14th
- I built a Firefox extension for Pokemon TCG players7th
- Hello from the new developer advocate (via Mozilla Add-ons Community Blog)1st
August
- The Firehose31st
July
- I wrote my first Dropzone 4 action28th
- Embracing failure20th
- Unit test your Python code in Jupyter Notebooks13th
- Appendix A to Developer's Guide to Communities8th
- Developer's Guide to Communities6th
June
- Javascript's console is so much more than just console.log29th
- A lighthouse22nd
- Goodbye, Futurice15th
- print is your best debugging tool8th
- GLC Decklist Validator updated with Astral Radiance1st
May
- Summer reading for scifi fans25th
- Learning Rust #9: A talk about rustlings18th
- A good job interview sets both sides up for success11th
- A week in life of a developer advocate4th
April
- Shy introvert's (short) guide to speaking in conferences27th
- Documentation: man pages vs tldr20th
- My trip to Django Day Copenhagen 2022 and Stockholm14th
March
- Listen to everyone, listen to no one30th
- Last two years have been awful23rd
- I'm speaking in Django Day Copenhagen 2022 in April16th
- Added custom highlight function for nhl-2359th
January
- Rant: Please stop ruining the search19th
- I started writing Weeklies12th
- My least favorite board game genre: co-op games5th
2021
December
- 45 stars, Christmas was almost saved - Advent of Code retrospective31st
- Year in Review 202129th
- Merry Christmas!22nd
- Tips for Advent of Code15th
- Advent of Code 20218th
- Customizing liiga.fi experience4th
- Minimal Travel Table Top Game Collection 3: Project 1081st
November
- Hello code, my old friend24th
- Reaction GIF board with Stream Deck17th
- The most social and loneliest job: being a solo developer advocate10th
October
- Tiny handy tools: Community Edition27th
- Tiny handy tools20th
- Over a year of weekly blogging13th
- Python 3.10 is out and I'm excited6th
September
- How would you compare two version numbers?29th
- Where do you see yourself in five years?22nd
- Roll and Write board games are awesome15th
- React Finland 2021 Recap8th
- Learning Rust #8: What's next?1st
August
- Syntax highlight all the things25th
- Blogging is my new favourite refactoring tool18th
- Your blog should have an RSS feed11th
- Learning Rust #7: Learn from the community4th
July
- Blog post filter with Netlify Functions28th
- Javascript Basics: Scope21st
- codebase ep. 4: Web Components with Matias14th
- Learning Rust #6: Understanding ownership in Rust7th
June
- My travel setup for Nintendo Switch30th
- Why scheduling Slack messages and emails is so valuable for community builders23rd
- My (career) story in tech and developer relations16th
- codebase ep. 3: PHP with Larry9th
- Learning Rust #5: Rustlings2nd
May
- My Employer Supports My Open Source Contributions (via honeypot.io)31st
- Does it make sense to finish what you started?26th
- Scheduling operations in Python19th
- codebase ep. 2: Clojure with Ykä12th
- Learning Rust #4: Parsing JSON with strong types5th
April
- Falling forward28th
- Documentation-driven command line tools in Python with docopt21st
- How Spice Program supported my creation of 235 (via Futurice.com)15th
- Introducing developer community show codebase14th
- Learning Rust #3: crates.io & publishing your package7th
March
- My pockets are full of games31st
- 5 minutes that changed my life24th
- How to parse command line arguments in Python17th
- I gamified my own blog10th
- Learning Rust #2: Option & Result3rd
February
- Learning in public24th
- Pattern matching is coming to Python17th
- My home office setup10th
- Learning Rust: Pattern Matching3rd
January
- Introducing: 23527th
- Project: card-print-css20th
- Thoughts on debugging13th
- You should start a blog today6th
2020
December
- Year in Review 202030th
- Merry Christmas my friends23rd
- Advent of Code #3: Slowing down16th
- Advent of Code #2: Borrows, unwraps and lots of compiler errors9th
- Advent of Code #1: Getting Started2nd
November
- Customize your Internet experience25th
- Added keyboard support to ON24 with bookmarklet18th
- Functions 10111th
- Coaching at codebar has given me a lot (via codebar blog)6th
- Validating dynamic data conditionally with Joi4th
October
- How to ask help for technical problems?28th
- It's time for a remote work retrospective21st
- Dev Diary #2: Working prototype18th
August
- The many designs of on-screen inputs26th
- Arts, crafts and software: enhancing Flamme Rouge19th
- Adding keyboard shortcuts to Viaplay12th
- Secret Santa PnP – Designer Diary #1: I made some cards! (via BoardGameGeek)9th
July
June
- Hidden Identity in Table Top Games17th
- I built a digital version of Black Hole game10th
- Different approaches to learning programming3rd
- Building Hobby Projects to Help Get Your First Programming Job (via honeypot.io)1st
May
- How to scrape a website with Python & BeautifulSoup27th
- Minimal Travel Table Top Game Collection 2: Social Distancing Edition25th
- Tips for giving talks online20th
- How to Get Overwhelmed in Tech (via honeypot.io)13th
- Dev Diary #1: Pokemon TCG Cube Draft13th
- <code>blocks6th
April
- True, True, True == (True, True, True) in Python30th
- Morning Coffee Projects: Youtube extension18th
- 8 tech podcasts I listen8th
- Testing lifehack: testlab repositories1st
March
- Building a website with a static site generator, part 3: Domain, Analytics and Forms25th
- Building a website with a static site generator, part 2: Eleventy18th
- Building a website with a static site generator, part 1: Setup11th
- How my site is built with Eleventy + Ghost6th
- New Guide - Humane Guide to Debugging Web Apps4th
February
January
2019
December
August
July
June
May
- Simple backend system for frontend workshops in Javascript29th
- Make your function calls more readable23rd
February
- How to enable SSL in Netlify with custom domain14th
- PHP needs its own ES67th
- “Event is over and it was a failure. What happened?” — Pre-mortem can help you avoid pitfalls5th
January
- Event organizer - automate what you can, focus on people with all you’ve got31st
- Better bash history search with McFly28th
- Post a message from Slack to Twitter with Zapier27th
- Learning programming has never been more accessible in Helsinki17th
2018
December
November
July
June
- The Reset Button29th
- The Cost of a Purchase22nd
- Space has a Tendency to Fill Itself15th
- My love-hate relationship with PHP Arrays13th
- Beginning of a Journey8th
- What living a minimalistic life has taught me8th
May
March
February
- Food Connects People - How to Hack Your Community with Food22nd
- Communities in Marketing16th
- How I convinced 15+ companies to contribute to OSS7th
January
2017
December
September
June
May
April
March
2016
December
- Build your community like a garden22nd
- What Rails Girls taught me about non-organizations19th
- Building a developer community calls for strong support13th
- Year in Review 201611th
August
2015
December
April
2014
September
August
July
June
January
2013
November
October
September
June
- 69 Lines of SQL30th