Advertisement · 728 × 90

Posts by justin

Making a Type Checker/LSP for Nix Building a TypeScript-style type checker and LSP for Nix with algebraic subtyping and negation types

Finally sharing out the type checker and LSP I made for nix

johns.codes/blog/making-...

Its really good! give it a shot

2 weeks ago 0 1 0 0

remember when the pedantic programmers were talking about how we'd be using diffs of ASTs and shit for git and people talking about text diffs were stupid? well then

3 weeks ago 1 0 0 0

all the talk about v_rc_l recently because of the ceo but i just want to get rid of it because it doesn't meet expectations more than anything

3 weeks ago 0 0 0 0

surely there must be a k9s tool out there that actually caches results and lets me do fast local editing and all? the typical k9s experience of scrolling, /search, enter, j, e, etc. is all so painfully slow

4 weeks ago 0 0 0 0

im on team cursor = text height?

1 month ago 1 0 1 0

multilingual gibberish tweets because some of these things are specific to what im talking about and ambiguous when poorly translated to english

1 month ago 0 0 0 0

you see the difference in how the products are made too. like the amount and concentration of soup in 辛라면 vs the chinese brand noodles.

1 month ago 0 0 1 0
Advertisement
Post image Post image

on twitter, 華人 find the JP act of eating ramen and then dumping rice on the leftover soup sacrilegious. especially on 蘭州拉麵.

the difference between 湯飯,粥,and dumping rice on leftover 拉麵湯 is the whole double carbs thing. i think double carbs is something mostly only seen from 日本 and 韓國

1 month ago 0 1 1 0

wish nix eval got faster and there were reasonably simple options for eval caching but seems impossible now

1 month ago 1 0 0 0

dropped all usage of nix-shell 2 years ago. it's been great. i still do buildEnv and add paths to PATH though github.com/justinwoo/my...

1 month ago 0 0 1 0

usually bad but is supposed to be good
炒飯 fried rice
回鍋肉 twice cooked pork
擔擔麵 dandan noodles
宮保雞丁 kung pao chicken
小籠包 xiao long bao
炸醬麵 sauce noodles

1 month ago 1 0 0 0

can be good, mediocre
口水雞 spicy poached chicken
麻婆豆腐 mapo tofu
魚香茄子 sweet eggplant
重慶辣子雞 spicy chicken
烤串 meat on sticks
糖酸肉 sweet pork
孜然羊肉 cumin lamb but less good
酱猪耳 pig ears
水煮牛肉 beef in oil
乾扁X/乾鍋X "dry pot" something. spicy
螞蟻上樹 glass noodles and ground pork

1 month ago 1 0 1 0

quality of dishes ime in chinese restaurants (half assed translations)

usually good if on the menu:
鍋包肉 sweet pork
松鼠魚 sweet fish
酸菜白肉 sour cabbage stew
酸菜魚 spicy sour cabbage fish stew
開水白菜 fancy banquet broth cabbage
炒烤肉 cumin lamb stir fry
夫妻肺片 cold beef slices in chili oil

1 month ago 1 0 1 0

where can i get high quality data for TOCFL and HSK? it seems like most lists have all kinds of fucked up non-standard pinyin

1 month ago 1 0 0 0
Preview
typing — Support for type hints Source code: Lib/typing.py This module provides runtime support for type hints. Consider the function below: The function surface_area_of_cube takes an argument expected to be an instance of float,...

docs.python.org/3/library/ty...

1 month ago 1 0 0 0

no it's python

1 month ago 2 0 1 0

why would you call type parameters "subscripting"...

1 month ago 1 0 1 0
Advertisement
Post image

Damn this actually used to be good

3 months ago 1 0 0 0

Git sha just suck to use regardless

3 months ago 0 0 0 0
Package managers keep using git as a database, it never works out Using git as a database is a seductive idea. You get version history for free. Pull requests give you a review workflow. It’s distributed by design. GitHub will host it for free. Everyone already knows how to use it. Package managers keep falling for this. And it keeps not working out. ## Cargo The crates.io index started as a git repository. Every Cargo client cloned it. This worked fine when the registry was small, but the index kept growing. Users would see progress bars like “Resolving deltas: 74.01%, (64415/95919)” hanging for ages, the visible symptom of Cargo’s libgit2 library grinding through delta resolution on a repository with thousands of historic commits. The problem was worst in CI. Stateless environments would download the full index, use a tiny fraction of it, and throw it away. Every build, every time. RFC 2789 introduced a sparse HTTP protocol. Instead of cloning the whole index, Cargo now fetches files directly over HTTPS, downloading only the metadata for dependencies your project actually uses. (This is the “full index replication vs on-demand queries” tradeoff in action.) By April 2025, 99% of crates.io requests came from Cargo versions where sparse is the default. The git index still exists, still growing by thousands of commits per day, but most users never touch it. ## Homebrew GitHub explicitly asked Homebrew to stop using shallow clones. Updating them was “an extremely expensive operation” due to the tree layout and traffic of homebrew-core and homebrew-cask. Users were downloading 331MB just to unshallow homebrew-core. The .git folder approached 1GB on some machines. Every `brew update` meant waiting for git to grind through delta resolution. Homebrew 4.0.0 in February 2023 switched to JSON downloads for tap updates. The reasoning was blunt: “they are expensive to git fetch and git clone and GitHub would rather we didn’t do that… they are slow to git fetch and git clone and this provides a bad experience to end users.” Auto-updates now run every 24 hours instead of every 5 minutes, and they’re much faster because there’s no git fetch involved. ## CocoaPods CocoaPods is the package manager for iOS and macOS development. It hit the limits hard. The Specs repo grew to hundreds of thousands of podspecs across a deeply nested directory structure. Cloning took minutes. Updating took minutes. CI time vanished into git operations. GitHub imposed CPU rate limits. The culprit was shallow clones, which force GitHub’s servers to compute which objects the client already has. The team tried various band-aids: stopping auto-fetch on `pod install`, converting shallow clones to full clones, sharding the repository. The CocoaPods blog captured it well: “Git was invented at a time when ‘slow network’ and ‘no backups’ were legitimate design concerns. Running endless builds as part of continuous integration wasn’t commonplace.” CocoaPods 1.8 gave up on git entirely for most users. A CDN became the default, serving podspec files directly over HTTP. The migration saved users about a gigabyte of disk space and made `pod install` nearly instant for new setups. ## Go modules Grab’s engineering team went from 18 minutes for `go get` to 12 seconds after deploying a module proxy. That’s not a typo. Eighteen minutes down to twelve seconds. The problem was that `go get` needed to fetch each dependency’s source code just to read its go.mod file and resolve transitive dependencies. Cloning entire repositories to get a single file. Go had security concerns too. The original design wanted to remove version control tools entirely because “these fragment the ecosystem: packages developed using Bazaar or Fossil, for example, are effectively unavailable to users who cannot or choose not to install these tools.” Beyond fragmentation, the Go team worried about security bugs in version control systems becoming security bugs in `go get`. You’re not just importing code; you’re importing the attack surface of every VCS tool on the developer’s machine. GOPROXY became the default in Go 1.13. The proxy serves source archives and go.mod files independently over HTTP. Go also introduced a checksum database (sumdb) that records cryptographic hashes of module contents. This protects against force pushes silently changing tagged releases, and ensures modules remain available even if the original repository is deleted. ## Beyond package managers The same pattern shows up wherever developers try to use git as a database. Git-based wikis like Gollum (used by GitHub and GitLab) become “somewhat too slow to be usable” at scale. Browsing directory structure takes seconds per click. Loading pages takes longer. GitLab plans to move away from Gollum entirely. Git-based CMS platforms like Decap hit GitHub’s API rate limits. A Decap project on GitHub scales to about 10,000 entries if you have a lot of collection relations. A new user with an empty cache makes a request per entry to populate it, burning through the 5,000 request limit quickly. If your site has lots of content or updates frequently, use a database instead. Even GitOps tools that embrace git as a source of truth have to work around its limitations. ArgoCD’s repo server can run out of disk space cloning repositories. A single commit invalidates the cache for all applications in that repo. Large monorepos need special scaling considerations. ## The pattern The hosting problems are symptoms. The underlying issue is that git inherits filesystem limitations, and filesystems make terrible databases. **Directory limits.** Directories with too many files become slow. CocoaPods had 16,000 pod directories in a single Specs folder, requiring huge tree objects and expensive computation. Their fix was hash-based sharding: split directories by the first few characters of a hashed name, so no single directory has too many entries. Git itself does this internally with its objects folder, splitting into 256 subdirectories. You’re reinventing B-trees, badly. **Case sensitivity.** Git is case-sensitive, but macOS and Windows filesystems typically aren’t. Check out a repo containing both `File.txt` and `file.txt` on Windows, and the second overwrites the first. Azure DevOps had to add server-side enforcement to block pushes with case-conflicting paths. **Path length limits.** Windows restricts paths to 260 characters, a constraint dating back to DOS. Git supports longer paths, but Git for Windows inherits the OS limitation. This is painful with deeply nested node_modules directories, where `git status` fails with “Filename too long” errors. **Missing database features.** Databases have CHECK constraints and UNIQUE constraints; git has nothing, so every package manager builds its own validation layer. Databases have locking; git doesn’t. Databases have indexes for queries like “all packages depending on X”; with git you either traverse every file or build your own index. Databases have migrations for schema changes; git has “rewrite history and force everyone to re-clone.” The progression is predictable. Start with a flat directory of files. Hit filesystem limits. Implement sharding. Hit cross-platform issues. Build server-side enforcement. Build custom indexes. Eventually give up and use HTTP or an actual database. You’ve built a worse version of what databases already provide, spread across git hooks, CI pipelines, and bespoke tooling. None of this means git is bad. Git excels at what it was designed for: distributed collaboration on source code, with branching, merging, and offline work. The problem is using it for something else entirely. Package registries need fast point queries for metadata. Git gives you a full-document sync protocol when you need a key-value lookup. If you’re building a package manager and git-as-index seems appealing, look at Cargo, Homebrew, CocoaPods, Go. They all had to build workarounds as they grew, causing pain for users and maintainers. The pull request workflow is nice. The version history is nice. You will hit the same walls they did.

Package managers keep using git as a database, it never works out.

nesbitt.io/2025/12/24/package-manag...

3 months ago 169 89 7 2
Post image Post image

Northern country

5 months ago 0 0 0 0
Post image

November

5 months ago 3 0 0 0

my random opinion is that sram doubletap are so nice and i wish my shimano levers didnt let the entire fucking brake lever sponge around. the double tap release action is plasticky and whatnot but it sets all at once, whereas the gear action also feels mushy as hell even in the mid tier groupsets

5 months ago 0 0 0 0

the year is 2025. i am still looking for ways to guarantee shit goes into the cabal store instead of dist-newstyle. if i ever need a job with more frustrating build tools and longer build times i'll find a rust job

5 months ago 1 0 0 0
Post image

Text inputs that don’t trigger spell check 2025

5 months ago 1 0 0 0
Advertisement

i posted 4 months ago

6 months ago 0 0 0 0

i wrote about having to move away from trusty old nix-env recently, being unable to nix-profile at all in nix >2.9

github.com/justinwoo/my...

10 months ago 1 0 0 0

sorry, it looks like my problem actually might be half because of eelco

10 months ago 0 0 0 0
Post image

annoying to have had to change my workflow from pedantic nixpkgs maintainers who don't put any effort in enriching the errors they throw. i could be convinced to change, but now i'm feeling like i should stop using nix more and more github.com/justinwoo/.d...

10 months ago 0 0 1 0

you should learn the lyrics of hanabi and bust it out every time

11 months ago 1 0 0 0