Evan Hahn's blog
Subscribe with RSS or email, if you want.
2024
- Clojure: distinct versus dedupe
- Remember The Milk script to estimate selected tasks
- How to use crypto.timingSafeEqual with strings
- What's the best way to concatenate Uint8Arrays?
- systemd-inhibit: a built-in Linux alternative to macOS's "caffeinate" command
- import myModule from "./my-module.torrent": requiring Node modules from BitTorrent
- Remember The Milk CSV export script
- The world's smallest PNG
- Torrent snapshot of my open source projects, as of 2024
2023
- Introducing Sqids Crystal
- When static types make your code shorter
- How to do integer division in Crystal
- How sleep mode works on the Anbernic RG35XX (with GarlicOS)
- Introducing NONOGRAM NIGHTS
- How to use the JavaScript Compression Streams API to (de)compress strings
- Things I wish I knew about the Ocarina of Time Randomizer
- Conditional Express middleware
- Track flights on iOS without installing anything
- How big is a kilobyte?
- How does Swift decode "weird" JSON numbers?
- Short C program that repeats a string forever
- "JavaScript and the farmer emoji": my talk at the Chicago JavaScript Meetup
- My mnemonic to remember tar commands on Linux
- How to set the (deprecated) valign attribute with JavaScript
- Subscribe with email if you want
- Play a jingle on Git commits
- Which Zelda dungeons are actually called "dungeons"?
- Proof of concept: drop-in JSON replacement that produces smaller payloads
- A picross game in 1024 bytes
- What's the largest possible PNG?
- You might not need Helmet.js
- Python's nonstandard JSON encoding
- Crystal: how to compute a CRC32 checksum
- Getting the UTF-16 bytes of JavaScript strings
- Getting the UTF-32 bytes of JavaScript strings
- Working with the UTF-8 bytes of JavaScript strings
- Introducing UTF-21, a toy character encoding
- My favorite little Markdown feature: reordering ordered lists
- How to compute the distance between two Cartesian points in JavaScript
- Why does "👩🏾🌾" have a length of 7 in JavaScript?
- Converting UIColors to CSS colors
- Everything we know about The Legend of Zelda: Tears of the Kingdom, as of April 2023
- Nested array permutations in JavaScript
- The lone developer problem
- Everything we know about The Legend of Zelda: Tears of the Kingdom, as of February 2023
- How to format SQLite BLOB columns as hex
- 9 years maintaining a sorta-popular open source package: lessons learned
- How I fixed broken Wi-Fi on my 2012 Mac Mini running Zorin OS
- Everything we know about The Legend of Zelda: Tears of the Kingdom, as of January 2023
2022
- Everything we know about The Legend of Zelda: Tears of the Kingdom, as of December 2022
- Ruby: how to get the MD5 hash of a file
- Everything we know about The Legend of Zelda: Tears of the Kingdom, as of November 2022
- Everything we know about The Legend of Zelda: Tears of the Kingdom, as of September 2022
- Re-implementing JavaScript's == in JavaScript
- Use Node built-ins to test small projects
- Everything we know about The Legend of Zelda: Tears of the Kingdom, as of August 2022
- The difference between "=" and "IS" in SQLite
- A decade of dotfiles
- Disable SwiftLint for a file
- Everything we know about The Legend of Zelda: Tears of the Kingdom, as of May 2022
- How to read tab-separated values (TSV) files in Python
- Remember The Milk script to find tasks with invalid start times
- Everything we know about The Legend of Zelda: Tears of the Kingdom, as of April 2022
2021
2020
2019
2018
- An interview with me on JavaScript Jabber
- "Fancy code is exclusionary"
- My entry to JS1k 2018: "Zap"
- Show only production dependencies with npm
- On modern censorship
2017
- Import Pinboard bookmarks into Standard Notes
- On multi-paradigm languages
- "Facebook Wins, Democracy Loses"
- Clojure's "zero?" has some quirks
- Petition to open source Flash
- Lessons learned from last week's cyberattack
- Think of the journalists
- Ball lightning
- On becoming comfortable with privacy violations
- "Six other times the US has banned immigrants"
- Z-index seems so simple...
- Prevent Homebrew from gathering analytics
2016
- Automatically ls when changing directories in zsh
- "If my code helped one developer at least once"
- "X marks gender-neutral"
- "The last thing we all need is for the 'data' economy to destroy another medium"
- How to empty Chrome's cache and do a hard reload
- Detect global JavaScript variables with iframes
- Parse URLs with <a> tags in JavaScript
2015
- How to transfer Android Neko Atsume saves using adb
- Disable ESLint for a file
- The CSP module is the largest part of Helmet
- Vim's :x command
- Only customize where you are unusual
- Programming languages and their ecosystems
- How to clear all inline styles from an HTML element
- Overwriting document.head in strict mode on Safari
- Pietime, my entry to JS1k 2015
- "This Incredible Hospital Robot Is Saving Lives. Also, I Hate It"
- Scrape Delicious bookmarks with 3 command-line tools
- Skip the header of a file with Python's CSV reader
- "Raising the wall" for open source
- Install a list of Atom packages from a file
2014
- Firefox preferences in dotfiles with Vimperator
- Thoughts on CoffeeScript after ECMAScript 6
- Disable the beer emoji in Homebrew
- The Internet no longer a wild west
- A deep dive into Express's static middleware
- Mostly on screens, at scales unimaginable
- A quick romp through default values in CoffeeScript
- Install Node Version Manager without the source line
- "About Feminism"
- "Writing the code was typically less than half the problem"
- "Is it more readable? Is it more clear?"
- Bitcoin prices with a shell one-liner
- The Internet as public infrastructure
- "We Are All Intelligence Officers Now"
- Strangecoin
- Dealing with the User-Agent of Python's Requests library
- "Is jQuery too big for mobile?"
- Publishing a simple package to npm
- Understanding Express.js
- Disable JSHint for a file
- Introducing cyborg.txt: robots.txt utilities for Node
2013
- Proteus
- The Underhanded C Contest
- Two-factor authentication list
- An experiment: syntax highlighting for the English language
- Origin: my entry to js13kgames 2013
- Visualizing cracking AES-256
- Gribbagrab your resources
- Four CSS tips that have changed me
- Vim's dw_red for terminal Vim
- "JavaScript folks are really nuts"
- Understanding Express.js version 3
- Concept: making asynchronous loading look synchronous
- Resources from my 6th semester at the University of Michigan
- The intended purposes of JavaScript and the Internet
- "All magic comes with a price"
- "Vim's killer feature"
- Backbone.js is larger than you think
- Michigan students can use Virtual Sites to do cross-browser testing
- "Using the web in 2013 means using JavaScript"
- HTML and the "living standard"
- Circles 1K
- Why should AI be humanlike?
2012
- Are we shook up?
- Resources from my 5th semester at the University of Michigan
- Why GNU grep is fast
- Smoothing out setTimeout in CoffeeScript
- "Ramadan code"
- Detect the Vimium Chrome extension
- Under 1% of English words are alphabetical
- "Technology itself does not transform anything"
- "10 Timeframes"
- My rules of thumb for extending JavaScript native objects
- Private members in CoffeeScript
- First impressions of Rails
- JavaScript/CoffeeScript sleepsort
- On my internship at UniversityNow
- Meeting the computer halfway
- Nicer committing with Vim
- Start Vim and temporarily ignore your .vimrc
- Evan Hahn's lil' pages
- Timeline of sexist incidents in geek communities
- Hardware Vim petal
- CoffeeScript's existential operator
- Airplane mode
- Cancel a git-flow branch
- Make console methods work in Internet Explorer
- Apple and the majority
- Is it worth cheating Caltrain?
- Week three of Vim
- Maurice Sendak
- The most important decisions are non-technical
- LinkedIn's app is HTML5
- Caesar shift in JavaScript and CoffeeScript
- What the Google-Oracle trials mean for coders
- Doing without jQuery
- Douglas Crockford on making JSON a standard
- Resources from my 4th semester at the University of Michigan
- Quietly awesome
- Papyrus Watch
- The Midwest Mentality
- "Inventing on principle"
- "We actually think people have to pay for content."
- Evil sum and average of a JavaScript array
- Nintendo's changing logo
- My C++ pointers reference
- Post-active state for links
- I love CoffeeScript
- Remove one element by index from JavaScript array
- Resources from my 3rd semester at the University of Michigan
2011
- "Traditional" for loops in CoffeeScript
- The comprehensive guide to disabling selection on the web
- Newline necessary at the end of JavaScript files?
- How to code Tic-Tac-Toe (and a Lua implementation)
- Detect the RockMelt browser from JavaScript
- Randomly generate either -1 or 1 in JavaScript
- How do I Jasmine: a tutorial
- Naps and their effectiveness
- Old Notational Velocity icon
- Use text-to-speech if you can't proofread aloud
- Only organize when you cannot search
- Euler method calculator in C++