# Julia Evans

Julia Evans

This is one page of public article previews, not the complete archive. Follow Next page to continue. Summaries are not the original full articles.

## Some more things about Django I've been enjoying

DevFeed: [Some more things about Django I've been enjoying](<https://devfeed.tech/articles/some-more-things-about-django-i-ve-been-enjoying-21131.md>)

Original publisher: [Read original article](<https://jvns.ca/blog/2026/07/21/more-nice-django-things/>)

Author: Julia Evans

Published: 2026-07-21T00:00:00Z

Content type: opinion

Language: en

Sources: [Julia Evans](<https://devfeed.tech/sources/julia-evans.md>)

Topics: [Django](<https://devfeed.tech/topics/django.md>), [Back end](<https://devfeed.tech/topics/backend.md>), [Databases](<https://devfeed.tech/topics/databases.md>), [HTML](<https://devfeed.tech/topics/html.md>), [SQL](<https://devfeed.tech/topics/sql.md>), [JavaScript](<https://devfeed.tech/topics/javascript.md>), [Gin](<https://devfeed.tech/topics/gin.md>), [Python](<https://devfeed.tech/topics/python.md>), [Single-page application (SPA)](<https://devfeed.tech/topics/spa.md>), [Vue.js](<https://devfeed.tech/topics/vue.md>)

Tags: [backend](<https://devfeed.tech/tags/backend.md>), [database](<https://devfeed.tech/tags/database.md>), [django](<https://devfeed.tech/tags/django.md>), [flask](<https://devfeed.tech/tags/flask.md>), [go](<https://devfeed.tech/tags/go.md>), [html](<https://devfeed.tech/tags/html.md>), [javascript](<https://devfeed.tech/tags/javascript.md>), [sql](<https://devfeed.tech/tags/sql.md>), [vue](<https://devfeed.tech/tags/vue.md>)

### AI overview

The article shares the author's experience learning to build multi-page websites in a backend-focused style using Django, an SQL database, and server-rendered HTML. It discusses Django query sets and template filters, compares this approach with frontend-heavy JavaScript, Vue.js, Go, and Flask projects, and mentions some unresolved issues with Django.

### Source excerpt

Hello! I'm on a funny journey right now where I'm trying to learn how to make websites in a sort of 2010 style, where I have an SQL database and render some HTML on the backend. It's kind of an interesting journey because it doesn't necessarily feel "easy" to me to make websites in this way: I never learned how to do it in the 2000s or 2010s, and there's a lot I need to learn. So here are some Django features that make building this kind of site feel more achievable than when I was trying and failing to use Go's standard library or Flask. And I'll talk about a couple of issues with Django I've run into. why learn to make websites like it's 2010? Previously the toolkit I felt confident with for making websites was: static site generators (like for this blog) static sites that do some fun stuff with Javascript (like this sql playground) simple Vue.js single page apps with either a Lambda as a backend or a Go backend (like mess with dns) I really liked this frontend-heavy approach for these super simple applications but when I started thinking about making something with a lot of different pages (instead of literally just one page), I didn't feel so excited about the options I saw that involved a lot of frontend code. So I figured I'd try the backend. Writing a backend-focused site that uses as little JS as possible feels the same to me in a way as writing a single-page JS website that does as little on the backend as possible, even though they might seem like opposites. In both cases I'm just trying to keep as much of the logic as possible in one place. Now for some thoughts about Django! I'm enjoying query builders I learned that I can define a "query set" class in Django with a bunch of methods with different WHERE statements I might want to use while constructing a query: Here's how I use it in my view code once I've defined what all the methods mean: Events.objects.approved() .for_tab(tab) .with_festivals(tab_params.festival_slugs) .is_free(tab_params.free) .is_ou

## Learning a few things about running SQLite

DevFeed: [Learning a few things about running SQLite](<https://devfeed.tech/articles/learning-a-few-things-about-running-sqlite-21130.md>)

Original publisher: [Read original article](<https://jvns.ca/blog/2026/07/17/learning-about-running-sqlite/>)

Author: Julia Evans

Published: 2026-07-17T00:00:00Z

Content type: article

Language: en

Sources: [Julia Evans](<https://devfeed.tech/sources/julia-evans.md>)

Topics: [SQLite](<https://devfeed.tech/topics/sqlite.md>), [Django](<https://devfeed.tech/topics/django.md>), [Object-relational mapping](<https://devfeed.tech/topics/orm.md>), [Query (disambiguation)](<https://devfeed.tech/topics/query.md>), [Statistics](<https://devfeed.tech/topics/statistics.md>)

Tags: [blog](<https://devfeed.tech/tags/blog.md>), [django](<https://devfeed.tech/tags/django.md>), [orm](<https://devfeed.tech/tags/orm.md>), [search](<https://devfeed.tech/tags/search.md>), [sqlite](<https://devfeed.tech/tags/sqlite.md>), [statistics](<https://devfeed.tech/tags/statistics.md>)

### AI overview

A personal account of operating SQLite in production for a small Django website. The article describes how running ANALYZE dramatically improved an SQLite FTS5 query and discusses the difficulty of cleaning up large numbers of rows without blocking other database writers.

### Source excerpt

Hello! I've been working on a Django site recently, and I decided to use SQLite as the database. When I was getting started with using SQLite as database for a website I read a bunch of blog posts about how it is totally fine to use SQLite in production for a small site and I think it is totally fine, but what I did not fully appreciate is that SQLite is still a database, databases are complicated, and I do not know a lot about operating databases. So here are a couple of small things I've been learning about running SQLite. This is the 4th website I've used SQLite for, and I think this one is harder because with the power of the Django ORM I've been making the database do more work than I was previously without Django. I started by turning on WAL mode like all the blog posts said to do and hoping for the best. ANALYZE is apparently important Today I was running a query (using SQLite's FTS5 for full-text search) on a table with 4000 rows and it took 5 seconds. That seemed wrong to me: computers are fast! It turned out that what I needed to do was to run ANALYZE! Immediately the problem query went from taking 5 seconds to like 0.05 seconds (or some other number small enough that I didn't care to investigate further). I still don't know exactly what went wrong in the query plan, but my best guess is that it was some sort of accidentally quadratic thing. ANALYZE generates "statistics" (I guess about the number of rows in each table? and presumably other things?) so that the query planner can make better choices. Maybe one day I'll learn to read a query plan. cleaning up the database is tricky Occasionally I've run into situations where I accidentally put a bunch of rows in my database that I don't want to be there (for example completed tasks from django-tasks-db), and I want to clean them up. What's happened to me a few times in this case is: I run some kind of command to clean up the rows The command takes more than 5 seconds, since there are a lot of rows (though I

## Moving away from Tailwind, and learning to structure my CSS

DevFeed: [Moving away from Tailwind, and learning to structure my CSS](<https://devfeed.tech/articles/moving-away-from-tailwind-and-learning-to-structure-my-css-21129.md>)

Original publisher: [Read original article](<https://jvns.ca/blog/2026/05/15/moving-away-from-tailwind--and-learning-to-structure-my-css-/>)

Author: Julia Evans

Published: 2026-05-15T00:00:00Z

Content type: article

Language: en

Sources: [Julia Evans](<https://devfeed.tech/sources/julia-evans.md>)

Topics: [CSS](<https://devfeed.tech/topics/css.md>), [Tailwind CSS](<https://devfeed.tech/topics/tailwind.md>), [Front end](<https://devfeed.tech/topics/frontend.md>), [CSS Resets](<https://devfeed.tech/topics/css-reset.md>), [Code](<https://devfeed.tech/topics/code.md>), [Responsive Design](<https://devfeed.tech/topics/responsive-design.md>)

Tags: [code](<https://devfeed.tech/tags/code.md>), [css](<https://devfeed.tech/tags/css.md>), [frontend](<https://devfeed.tech/tags/frontend.md>), [how-to](<https://devfeed.tech/tags/how-to.md>), [responsive-design](<https://devfeed.tech/tags/responsive-design.md>), [tailwind](<https://devfeed.tech/tags/tailwind.md>)

### AI overview

The author describes migrating several sites from Tailwind to semantic HTML and vanilla CSS, using lessons from Tailwind to create clearer systems for structuring CSS. The article discusses resets, components, colors, font sizes, utility classes, spacing, responsive design, and the build system.

### Source excerpt

Hello! 8 years ago, I wrote excitedly about discovering Tailwind. At that time I really had no idea how to structure my CSS code and given the choice between a pile of complete chaos and Tailwind, I was really happy to choose Tailwind. It helped me make a lot of tiny sites! I spent the last week or so migrating a couple of sites away from Tailwind and towards more semantic HTML + vanilla CSS, and it was SO fun and SO interesting, so here are some things I learned! As usual I'm not a full-time frontend developer and so all of my CSS learning has happened in fits and starts over many years. it turns out Tailwind taught me a lot When I started thinking about structuring CSS, I was intimidated at first: I'm not very good at structuring my CSS! But then I started reading blog posts talking about how to structure CSS (like A whole cascade of layers or How I write CSS in 2024) and I realized a couple of things: Every CSS code base has a bunch of different things going on (layouts! fonts! colours! common components!) It's extremely useful to have systems or guidelines to manage each of those things, otherwise things descend into chaos Tailwind has systems for some of these, and I already know those systems! Maybe I can imitate the systems I like! For example, Tailwind has: a reset stylesheet a colour palette a font scale the systems I'm going to talk about I'm going to talk about a few aspects of my CSS codebase and my thoughts so far what kind of rules I want to impose on the codebase for each one. Some of them are copied from Tailwind and some aren't. reset components colours font sizes utility classes the base spacing responsive design the build system 1. reset I just copied Tailwind's "preflight styles" by going into tailwind.css and copying the first 200 lines or so. I noticed that I've developed a relationship with Tailwind's CSS reset over time, for example Tailwind sets box-sizing: border-box on every element (which means that an element's width includes its padding

## Links to CSS colour palettes

DevFeed: [Links to CSS colour palettes](<https://devfeed.tech/articles/links-to-css-colour-palettes-21128.md>)

Original publisher: [Read original article](<https://jvns.ca/blog/2026/05/04/css-colour-palettes/>)

Author: Julia Evans

Published: 2026-05-04T00:00:00Z

Content type: article

Language: en

Sources: [Julia Evans](<https://devfeed.tech/sources/julia-evans.md>)

Topics: [CSS](<https://devfeed.tech/topics/css.md>), [Tailwind CSS](<https://devfeed.tech/topics/tailwind.md>), [Accessibility](<https://devfeed.tech/topics/accessibility.md>), [Awesome Lists](<https://devfeed.tech/topics/awesome.md>)

Tags: [accessibility](<https://devfeed.tech/tags/accessibility.md>), [blog-post](<https://devfeed.tech/tags/blog-post.md>), [css](<https://devfeed.tech/tags/css.md>), [links](<https://devfeed.tech/tags/links.md>)

### AI overview

The article links to CSS colour palettes, including uchū, flexoki, and reasonable colours, with the latter noted for its accessibility focus. It also links to colour palette generators and tools such as colorhexa, and mentions using the oklch CSS function to generate colours dynamically.

### Source excerpt

A while back I decided to stop using Tailwind for new projects and to just write vanilla CSS instead. But one thing I missed about Tailwind was the colour palette (here as CSS). If I wanted a light blue I could just use blue-100 and if I didn't like it maybe try blue-200 or blue-50. I'm not very good with colours so it makes a big difference to me to have a reasonable colour palette that somebody who is better at colour than me has thought about. But I'm also a little tired of those Tailwind colours, so I asked on Mastodon today what other colour palettes were out there. And then a friend said they wanted links to those colour palettes, so here's a blog post so my friend can see them, and all the rest of you too :) my favourites The ones I liked the most were: uchū (css file, FAQ) flexoki (css file) reasonable colours, which seems to have a focus on accessibility (css file) more colour palettes web awesome radix US web design systems material design colourscheme generators Folks also linked to a bunch of colour palette generators harmonizer tints.dev coolors colorpalette.pro I've always found these types of generators too hard to use but maybe one day I will get better enough at colour that I'm able to use a colour palette generator successfully so I'll leave those links there anyway. and more colour tools: colorhexa has some info about colorblindness oklch Generative colors with CSS gives an example of how to use the oklch CSS function to dynamically generate colors.

## Testing Vue components in the browser

DevFeed: [Testing Vue components in the browser](<https://devfeed.tech/articles/testing-vue-components-in-the-browser-21127.md>)

Original publisher: [Read original article](<https://jvns.ca/blog/2026/05/02/testing-vue-components-in-the-browser/>)

Author: Julia Evans

Published: 2026-05-02T00:00:00Z

Content type: article

Language: en

Sources: [Julia Evans](<https://devfeed.tech/sources/julia-evans.md>)

Topics: [Vue.js](<https://devfeed.tech/topics/vue.md>), [Testing](<https://devfeed.tech/topics/testing.md>), [Front end](<https://devfeed.tech/topics/frontend.md>), [JavaScript](<https://devfeed.tech/topics/javascript.md>), [browser](<https://devfeed.tech/topics/browser.md>), [Playwright](<https://devfeed.tech/topics/playwright.md>)

Tags: [browser](<https://devfeed.tech/tags/browser.md>), [frontend](<https://devfeed.tech/tags/frontend.md>), [javascript](<https://devfeed.tech/tags/javascript.md>), [playwright](<https://devfeed.tech/tags/playwright.md>), [testing](<https://devfeed.tech/tags/testing.md>), [vue](<https://devfeed.tech/tags/vue.md>)

### AI overview

The article explains how to test Vue components directly in the browser without relying on Node, Deno, or another server-side JavaScript runtime. It describes moving beyond unit tests toward end-to-end integration tests, using QUnit and rerunning individual tests to make debugging network-heavy tests easier.

### Source excerpt

Hello! One of my long term projects on here is figuring out how to write frontend Javascript without using Node or any other server JS runtime. One issue I run into a lot in my frontend JS projects is that I don't know how to write tests for them. I've tried to use Playwright in the past, but it felt slow and unwieldy to be starting these new browser processes all the time, and it involved some Node code to orchestrate the tests. The result is that I just don't test my frontend code which doesn't feel great. Usually I don't update my projects much either so it doesn't come up that much, but it would be nice to be able to make changes with more confidence! So a way to do frontend testing that I like has been on my wishlist for a long time. idea: just run the tests in the browser tab Alex Chan wrote a great post a while back called Testing JavaScript without a (third-party) framework in response to one of my previous posts in this series that explained how to write a tiny unit-testing framework that runs in a page in browser. I loved this post at the time, but it only talked about unit testing and I wanted to write end-to-end integration tests for my Vue components, and I didn't know how to do that. So when I was talking to Marco the other day and he said something like "you know, you can just run tests for your Vue components in the browser", I thought "hey, I should try that again!!!" I just did all of this yesterday so certainly there's a lot to improve but I wanted to write down a few things I noticed about the process before I forget. This was a bit tricky for me because the Vue site usually assumes that you're using Node as part of your build process in some way (there's a lot of "step 1: npm install THING), and I didn't want to use Node/Deno/etc. But it turned out to not be too complicated. The project I'm going to talk about testing is this zine feedback site I wrote in 2023. the test framework: QUnit I used QUnit. It worked great but I don't have anything int

## Examples for the tcpdump and dig man pages

DevFeed: [Examples for the tcpdump and dig man pages](<https://devfeed.tech/articles/examples-for-the-tcpdump-and-dig-man-pages-21126.md>)

Original publisher: [Read original article](<https://jvns.ca/blog/2026/03/10/examples-for-the-tcpdump-and-dig-man-pages/>)

Author: Julia Evans

Published: 2026-03-10T00:00:00Z

Content type: article

Language: en

Sources: [Julia Evans](<https://devfeed.tech/sources/julia-evans.md>)

Topics: [Documentation](<https://devfeed.tech/topics/documentation.md>), [Tool](<https://devfeed.tech/topics/tool.md>), [Maintainers](<https://devfeed.tech/topics/maintainers.md>), [Learning](<https://devfeed.tech/topics/learning.md>), [Markdown](<https://devfeed.tech/topics/markdown.md>)

Tags: [beginners](<https://devfeed.tech/tags/beginners.md>), [blog-post](<https://devfeed.tech/tags/blog-post.md>), [docs](<https://devfeed.tech/tags/docs.md>), [documentation](<https://devfeed.tech/tags/documentation.md>), [examples](<https://devfeed.tech/tags/examples.md>), [learning](<https://devfeed.tech/tags/learning.md>), [maintainers](<https://devfeed.tech/tags/maintainers.md>), [markdown](<https://devfeed.tech/tags/markdown.md>), [tool](<https://devfeed.tech/tags/tool.md>), [writing](<https://devfeed.tech/tags/writing.md>)

### AI overview

The article describes adding beginner-friendly examples to the dig and tcpdump man pages. It explains why accurate, reviewed official documentation is valuable and notes that maintainers can provide useful details that are easy to miss. The author also describes using a basic Markdown-to-roff script for man-page updates.

### Source excerpt

Hello! My big takeaway from last month's musings about man pages was that examples in man pages are really great, so I worked on adding (or improving) examples to two of my favourite tools' man pages. Here they are: the dig man page (now with examples) the tcpdump man page examples (this one is an update to the previous examples) the goal: include the most basic examples The goal here was really just to give the absolute most basic examples of how to use the tool, for people who use tcpdump or dig infrequently (or have never used it before!) and don't remember how it works. So far saying "hey, I want to write an examples section for beginners and infrequent users of this tools" has been working really well. It's easy to explain, I think it makes sense from everything I've heard from users about what they want from a man page, and maintainers seem to find it compelling. Thanks to Denis Ovsienko, Guy Harris, Ondřej Surý, and everyone else who reviewed the docs changes, it was a good experience and left me motivated to do a little more work on man pages. why improve the man pages? I'm interested in working on tools' official documentation right now because: Man pages can actually have close to 100% accurate information! Going through a review process to make sure that the information is actually true has a lot of value. Even with basic questions "what are the most commonly used tcpdump flags", often maintainers are aware of useful features that I'm not! For example I learned by working on these tcpdump examples that if you're saving packets to a file with tcpdump -w out.pcap, it's useful to pass -v to print a live summary of how many packets have been captured so far. That's really useful, I didn't know it, and I don't think I ever would have noticed it on my own. It's kind of a weird place for me to be because honestly I always kind of assume documentation is going to be hard to read, and I usually just skip it and read a blog post or Stack Overflow comment or ask a f

## Notes on clarifying man pages

DevFeed: [Notes on clarifying man pages](<https://devfeed.tech/articles/notes-on-clarifying-man-pages-21125.md>)

Original publisher: [Read original article](<https://jvns.ca/blog/2026/02/18/man-pages/>)

Author: Julia Evans

Published: 2026-02-18T00:00:00Z

Content type: opinion

Language: en

Sources: [Julia Evans](<https://devfeed.tech/sources/julia-evans.md>)

Topics: [Documentation](<https://devfeed.tech/topics/documentation.md>), [Cheat sheet](<https://devfeed.tech/topics/cheatsheet.md>), [Tool](<https://devfeed.tech/topics/tool.md>), [ASCII](<https://devfeed.tech/topics/ascii.md>), [Git](<https://devfeed.tech/topics/git.md>), [ls](<https://devfeed.tech/topics/ls.md>), [Perl](<https://devfeed.tech/topics/perl.md>)

Tags: [ascii](<https://devfeed.tech/tags/ascii.md>), [cheat-sheet](<https://devfeed.tech/tags/cheat-sheet.md>), [documentation](<https://devfeed.tech/tags/documentation.md>), [examples](<https://devfeed.tech/tags/examples.md>), [git](<https://devfeed.tech/tags/git.md>), [notes](<https://devfeed.tech/tags/notes.md>)

### AI overview

The article explores ways to make Unix man pages easier to navigate and more useful. It considers embedding concise cheat sheets, using terse SYNOPSIS sections with OPTIONS SUMMARY sections, grouping options by category, providing condensed ASCII layouts, and including practical examples.

### Source excerpt

Hello! After spending some time working on the Git man pages last year, I've been thinking a little more about what makes a good man page. I've spent a lot of time writing cheat sheets for tools (tcpdump, git, dig, etc) which have a man page as their primary documentation. This is because I often find the man pages hard to navigate to get the information I want. Lately I've wondering - could the man page itself have an amazing cheat sheet in it? What might make a man page easier to use? I'm still very early in thinking about this but I wanted to write down some quick notes. I asked some people on Mastodon for their favourite man pages, and here are some examples of interesting things I saw on those man pages. an OPTIONS SUMMARY If you've read a lot of man pages you've probably seen something like this in the SYNOPSIS: once you're listing almost the entire alphabet, it's hard ls [-@ABCFGHILOPRSTUWabcdefghiklmnopqrstuvwxy1%,] grep [-abcdDEFGHhIiJLlMmnOopqRSsUVvwXxZz] The rsync man page has a solution I've never seen before: it keeps its SYNOPSIS very terse, like this: Local: rsync [OPTION...] SRC... [DEST] and then has an "OPTIONS SUMMARY" section with a 1-line summary of each option, like this: --verbose, -v increase verbosity --info=FLAGS fine-grained informational verbosity --debug=FLAGS fine-grained debug verbosity --stderr=e|a|c change stderr output mode (default: errors) --quiet, -q suppress non-error messages --no-motd suppress daemon-mode MOTD Then later there's the usual OPTIONS section with a full description of each option. an OPTIONS section organized by category The strace man page organizes its options by category (like "General", "Startup", "Tracing", and "Filtering", "Output Format") instead of alphabetically. As an experiment I tried to take the grep man page and make an "OPTIONS SUMMARY" section grouped by category, you can see the results here. I'm not sure what I think of the results but it was a fun exercise. When I was writing that I was thinking

## Some notes on starting to use Django

DevFeed: [Some notes on starting to use Django](<https://devfeed.tech/articles/some-notes-on-starting-to-use-django-21124.md>)

Original publisher: [Read original article](<https://jvns.ca/blog/2026/01/27/some-notes-on-starting-to-use-django/>)

Author: Julia Evans

Published: 2026-01-27T00:00:00Z

Content type: article

Language: en

Sources: [Julia Evans](<https://devfeed.tech/sources/julia-evans.md>)

Topics: [Django](<https://devfeed.tech/topics/django.md>), [Framework](<https://devfeed.tech/topics/framework.md>), [Object-relational mapping](<https://devfeed.tech/topics/orm.md>), [Website](<https://devfeed.tech/topics/website.md>), [Database](<https://devfeed.tech/topics/database.md>), [Rails](<https://devfeed.tech/topics/rails.md>), [Laravel](<https://devfeed.tech/topics/laravel.md>)

Tags: [database](<https://devfeed.tech/tags/database.md>), [django](<https://devfeed.tech/tags/django.md>), [framework](<https://devfeed.tech/tags/framework.md>), [laravel](<https://devfeed.tech/tags/laravel.md>), [orm](<https://devfeed.tech/tags/orm.md>), [rails](<https://devfeed.tech/tags/rails.md>), [web](<https://devfeed.tech/tags/web.md>)

### AI overview

A developer shares notes from starting to use Django after previously trying Rails. They find Django's explicit project structure easier to return to after long breaks, appreciate its built-in and customizable admin interface, and are enjoying its ORM for expressing database relationships and queries with less code.

### Source excerpt

Hello! One of my favourite things is starting to learn an Old Boring Technology that I've never tried before but that has been around for 20+ years. It feels really good when every problem I'm ever going to have has been solved already 1000 times and I can just get stuff done easily. I've thought it would be cool to learn a popular web framework like Rails or Django or Laravel for a long time, but I'd never really managed to make it happen. But I started learning Django to make a website a few months back, I've been liking it so far, and here are a few quick notes! less magic than Rails I spent some time trying to learn Rails in 2020, and while it was cool and I really wanted to like Rails (the Ruby community is great!), I found that if I left my Rails project alone for months, when I came back to it it was hard for me to remember how to get anything done because (for example) if it says resources :topics in your routes.rb, on its own that doesn't tell you where the topics routes are configured, you need to remember or look up the convention. Being able to abandon a project for months or years and then come back to it is really important to me (that's how all my projects work!), and Django feels easier to me because things are more explicit. In my small Django project it feels like I just have 5 main files (other than the settings files): urls.py, models.py, views.py, admin.py, and tests.py, and if I want to know where something else is (like an HTML template) is then it's usually explicitly referenced from one of those files. a built-in admin For this project I wanted to have an admin interface to manually edit or view some of the data in the database. Django has a really nice built-in admin interface, and I can customize it with just a little bit of code. For example, here's part of one of my admin classes, which sets up which fields to display in the "list" view, which field to search on, and how to order them by default. @admin.register(Zine) class ZineAdmin(adm

## A data model for Git (and other docs updates)

DevFeed: [A data model for Git (and other docs updates)](<https://devfeed.tech/articles/a-data-model-for-git-and-other-docs-updates-21123.md>)

Original publisher: [Read original article](<https://jvns.ca/blog/2026/01/08/a-data-model-for-git/>)

Author: Julia Evans

Published: 2026-01-08T00:00:00Z

Content type: article

Language: en

Sources: [Julia Evans](<https://devfeed.tech/sources/julia-evans.md>)

Topics: [Git](<https://devfeed.tech/topics/git.md>), [Documentation](<https://devfeed.tech/topics/documentation.md>), [Maintainers](<https://devfeed.tech/topics/maintainers.md>), [Open Source](<https://devfeed.tech/topics/open-source.md>), [data](<https://devfeed.tech/topics/data.md>)

Tags: [docs](<https://devfeed.tech/tags/docs.md>), [documentation](<https://devfeed.tech/tags/documentation.md>), [git](<https://devfeed.tech/tags/git.md>), [maintainers](<https://devfeed.tech/tags/maintainers.md>), [open-source](<https://devfeed.tech/tags/open-source.md>), [review](<https://devfeed.tech/tags/review.md>)

### AI overview

The article describes updates to Git's official documentation, including a new data model explaining objects, references, indexes, commits, and branches. It also discusses improving Git's core man pages through review and feedback from about 80 test readers.

### Source excerpt

Hello! This past fall, I decided to take some time to work on Git's documentation. I've been thinking about working on open source docs for a long time - usually if I think the documentation for something could be improved, I'll write a blog post or a zine or something. But this time I wondered: could I instead make a few improvements to the official documentation? So Marie and I made a few changes to the Git documentation! a data model for Git After a while working on the documentation, we noticed that Git uses the terms "object", "reference", or "index" in its documentation a lot, but that it didn't have a great explanation of what those terms mean or how they relate to other core concepts like "commit" and "branch". So we wrote a new "data model" document! You can read the data model here for now. I assume at some point (after the next release?) it'll also be on the Git website. I'm excited about this because understanding how Git organizes its commit and branch data has really helped me reason about how Git works over the years, and I think it's important to have a short (1600 words!) version of the data model that's accurate. The "accurate" part turned out to not be that easy: I knew the basics of how Git's data model worked, but during the review process I learned some new details and had to make quite a few changes (for example how merge conflicts are stored in the staging area). updates to git push, git pull, and more I also worked on updating the introduction to some of Git's core man pages. I quickly realized that "just try to improve it according to my best judgement" was not going to work: why should the maintainers believe me that my version is better? I've seen a problem a lot when discussing open source documentation changes where 2 expert users of the software argue about whether an explanation is clear or not ("I think X would be a good way to explain it! Well, I think Y would be better!") I don't think this is very productive (expert users of a pie

## Notes on switching to Helix from vim

DevFeed: [Notes on switching to Helix from vim](<https://devfeed.tech/articles/notes-on-switching-to-helix-from-vim-21122.md>)

Original publisher: [Read original article](<https://jvns.ca/blog/2025/10/10/notes-on-switching-to-helix-from-vim/>)

Author: Julia Evans

Published: 2025-10-10T00:00:00Z

Content type: opinion

Language: en

Sources: [Julia Evans](<https://devfeed.tech/sources/julia-evans.md>)

Topics: [Vim](<https://devfeed.tech/topics/vim.md>), [Neovim](<https://devfeed.tech/topics/neovim.md>), [configuration](<https://devfeed.tech/topics/configuration.md>)

Tags: [comparison](<https://devfeed.tech/tags/comparison.md>), [configuration](<https://devfeed.tech/tags/configuration.md>), [switching](<https://devfeed.tech/tags/switching.md>), [vim](<https://devfeed.tech/tags/vim.md>)

### AI overview

The article records the author's experience switching from Vim and Neovim to the Helix text editor after three months of use. It discusses Helix's built-in language server support, repository search with match context, quick-reference help, multiple cursors, buffer switching, and several differences or annoyances compared with Vim and Neovim.

### Source excerpt

Hello! Earlier this summer I was talking to a friend about how much I love using fish, and how I love that I don't have to configure it. They said that they feel the same way about the helix text editor, and so I decided to give it a try. I've been using it for 3 months now and here are a few notes. why helix: language servers I think what motivated me to try Helix is that I've been trying to get a working language server setup (so I can do things like "go to definition") and getting a setup that feels good in Vim or Neovim just felt like too much work. After using Vim/Neovim for 20 years, I've tried both "build my own custom configuration from scratch" and "use someone else's pre-buld configuration system" and even though I love Vim I was excited about having things just work without having to work on my configuration at all. Helix comes with built in language server support, and it feels nice to be able to do things like "rename this symbol" in any language. the search is great One of my favourite things about Helix is the search! If I'm searching all the files in my repository for a string, it lets me scroll through the potential matching files and see the full context of the match, like this: For comparison, here's what the vim ripgrep plugin I've been using looks like: There's no context for what else is around that line. the quick reference is nice One thing I like about Helix is that when I press g, I get a little help popup telling me places I can go. I really appreciate this because I don't often use the "go to definition" or "go to reference" feature and I often forget the keyboard shortcut. some vim -> helix translations Helix doesn't have marks like ma, 'a, instead I've been using Ctrl+O and Ctrl+I to go back (or forward) to the last cursor location I think Helix does have macros, but I've been using multiple cursors in every case that I would have previously used a macro. I like multiple cursors a lot more than writing macros all the time. If I want to

## New zine: The Secret Rules of the Terminal

DevFeed: [New zine: The Secret Rules of the Terminal](<https://devfeed.tech/articles/new-zine-the-secret-rules-of-the-terminal-21121.md>)

Original publisher: [Read original article](<https://jvns.ca/blog/2025/06/24/new-zine--the-secret-rules-of-the-terminal/>)

Author: Julia Evans

Published: 2025-06-26T00:00:00Z

Content type: article

Language: en

Sources: [Julia Evans](<https://devfeed.tech/sources/julia-evans.md>)

Topics: [Terminal](<https://devfeed.tech/topics/terminal.md>), [Shell](<https://devfeed.tech/topics/shell.md>), [Command-line interface](<https://devfeed.tech/topics/cli.md>), [Operating system](<https://devfeed.tech/topics/operating-system.md>), [Software](<https://devfeed.tech/topics/software.md>)

Tags: [blog](<https://devfeed.tech/tags/blog.md>), [deep-dive](<https://devfeed.tech/tags/deep-dive.md>), [how-to](<https://devfeed.tech/tags/how-to.md>), [internals](<https://devfeed.tech/tags/internals.md>), [software](<https://devfeed.tech/tags/software.md>), [terminal](<https://devfeed.tech/tags/terminal.md>), [tips-and-tricks](<https://devfeed.tech/tags/tips-and-tricks.md>)

### AI overview

The article announces a zine about the terminal and explains why terminal behavior can feel inconsistent or difficult to investigate. It introduces the terminal as a combination of a terminal emulator, operating system, shell, core utilities, and other programs, and presents the zine as a guide to their interactions, common conventions, and practical usage tips.

### Source excerpt

Hello! After many months of writing deep dive blog posts about the terminal, on Tuesday I released a new zine called "The Secret Rules of the Terminal"! You can get it for $12 here: https://wizardzines.com/zines/terminal, or get an 15-pack of all my zines here. Here's the cover: the table of contents Here's the table of contents: why the terminal? I've been using the terminal every day for 20 years but even though I'm very confident in the terminal, I've always had a bit of an uneasy feeling about it. Usually things work fine, but sometimes something goes wrong and it just feels like investigating it is impossible, or at least like it would open up a huge can of worms. So I started trying to write down a list of weird problems I've run into in terminal and I realized that the terminal has a lot of tiny inconsistencies like: sometimes you can use the arrow keys to move around, but sometimes pressing the arrow keys just prints ^[[D sometimes you can use the mouse to select text, but sometimes you can't sometimes your commands get saved to a history when you run them, and sometimes they don't some shells let you use the up arrow to see the previous command, and some don't If you use the terminal daily for 10 or 20 years, even if you don't understand exactly why these things happen, you'll probably build an intuition for them. But having an intuition for them isn't the same as understanding why they happen. When writing this zine I actually had to do a lot of work to figure out exactly what was happening in the terminal to be able to talk about how to reason about it. the rules aren't written down anywhere It turns out that the "rules" for how the terminal works (how do you edit a command you type in? how do you quit a program? how do you fix your colours?) are extremely hard to fully understand, because "the terminal" is actually made of many different pieces of software (your terminal emulator, your operating system, your shell, the core utilities like grep, and every

## Using \`make\` to compile C programs (for non-C-programmers)

DevFeed: [Using \`make\` to compile C programs (for non-C-programmers)](<https://devfeed.tech/articles/using-make-to-compile-c-programs-for-non-c-programmers-21120.md>)

Original publisher: [Read original article](<https://jvns.ca/blog/2025/06/10/how-to-compile-a-c-program/>)

Author: Julia Evans

Published: 2025-06-10T00:00:00Z

Content type: tutorial

Language: en

Sources: [Julia Evans](<https://devfeed.tech/sources/julia-evans.md>)

Topics: [C](<https://devfeed.tech/topics/c.md>), [make](<https://devfeed.tech/topics/make.md>), [Compiler](<https://devfeed.tech/topics/compiler.md>), [Package manager](<https://devfeed.tech/topics/package-manager.md>), [gcc](<https://devfeed.tech/topics/gcc.md>), [apt](<https://devfeed.tech/topics/apt.md>), [Xcode](<https://devfeed.tech/topics/xcode.md>), [C++](<https://devfeed.tech/topics/c-plus-plus.md>)

Tags: [apt](<https://devfeed.tech/tags/apt.md>), [building](<https://devfeed.tech/tags/building.md>), [c](<https://devfeed.tech/tags/c.md>), [c-plus-plus](<https://devfeed.tech/tags/c-plus-plus.md>), [command-line](<https://devfeed.tech/tags/command-line.md>), [compiler](<https://devfeed.tech/tags/compiler.md>), [debian](<https://devfeed.tech/tags/debian.md>), [dependencies](<https://devfeed.tech/tags/dependencies.md>), [gcc](<https://devfeed.tech/tags/gcc.md>), [libraries](<https://devfeed.tech/tags/libraries.md>), [linux](<https://devfeed.tech/tags/linux.md>), [mac](<https://devfeed.tech/tags/mac.md>), [make](<https://devfeed.tech/tags/make.md>), [packages](<https://devfeed.tech/tags/packages.md>), [xcode](<https://devfeed.tech/tags/xcode.md>)

### AI overview

A beginner-oriented guide to compiling C programs from source, covering compiler installation, dependency discovery, and build tools on Ubuntu and macOS.

### Source excerpt

I have never been a C programmer but every so often I need to compile a C/C++ program from source. This has been kind of a struggle for me: for a long time, my approach was basically "install the dependencies, run make, if it doesn't work, either try to find a binary someone has compiled or give up". "Hope someone else has compiled it" worked pretty well when I was running Linux but since I've been using a Mac for the last couple of years I've been running into more situations where I have to actually compile programs myself. So let's talk about what you might have to do to compile a C program! I'll use a couple of examples of specific C programs I've compiled and talk about a few things that can go wrong. Here are three programs we'll be talking about compiling: paperjam sqlite qf (a pager you can run to quickly open files from a search with rg -n THING | qf) step 1: install a C compiler This is pretty simple: on an Ubuntu system if I don't already have a C compiler I'll install one with: sudo apt-get install build-essential This installs gcc, g++, and make. The situation on a Mac is more confusing but it's something like "install xcode command line tools". step 2: install the program's dependencies Unlike some newer programming languages, C doesn't have a dependency manager. So if a program has any dependencies, you need to hunt them down yourself. Thankfully because of this, C programmers usually keep their dependencies very minimal and often the dependencies will be available in whatever package manager you're using. There's almost always a section explaining how to get the dependencies in the README, for example in paperjam's README, it says: To compile PaperJam, you need the headers for the libqpdf and libpaper libraries (usually available as libqpdf-dev and libpaper-dev packages). You may need a2x (found in AsciiDoc) for building manual pages. So on a Debian-based system you can install the dependencies like this. sudo apt install -y libqpdf-dev libpaper-dev

## Standards for ANSI escape codes

DevFeed: [Standards for ANSI escape codes](<https://devfeed.tech/articles/standards-for-ansi-escape-codes-21119.md>)

Original publisher: [Read original article](<https://jvns.ca/blog/2025/03/07/escape-code-standards/>)

Author: Julia Evans

Published: 2025-03-07T00:00:00Z

Content type: article

Language: en

Sources: [Julia Evans](<https://devfeed.tech/sources/julia-evans.md>)

Topics: [Terminal](<https://devfeed.tech/topics/terminal.md>), [Code](<https://devfeed.tech/topics/code.md>), [Usability](<https://devfeed.tech/topics/usability.md>), [Command-line interface](<https://devfeed.tech/topics/cli.md>)

Tags: [code](<https://devfeed.tech/tags/code.md>), [improvements](<https://devfeed.tech/tags/improvements.md>), [remote](<https://devfeed.tech/tags/remote.md>), [standards](<https://devfeed.tech/tags/standards.md>), [terminal](<https://devfeed.tech/tags/terminal.md>), [usability](<https://devfeed.tech/tags/usability.md>)

### AI overview

An introduction to ANSI escape codes, their role in terminal input and output, their usability benefits, and the standards that define them. The article explains that incomplete standardization can make escape codes unreliable and difficult to troubleshoot, and discusses ECMA-48 as an early standard.

### Source excerpt

Hello! Today I want to talk about ANSI escape codes. For a long time I was vaguely aware of ANSI escape codes ("that's how you make text red in the terminal and stuff") but I had no real understanding of where they were supposed to be defined or whether or not there were standards for them. I just had a kind of vague "there be dragons" feeling around them. While learning about the terminal this year, I've learned that: ANSI escape codes are responsible for a lot of usability improvements in the terminal (did you know there's a way to copy to your system clipboard when SSHed into a remote machine?? It's an escape code called OSC 52!) They aren't completely standardized, and because of that they don't always work reliably. And because they're also invisible, it's extremely frustrating to troubleshoot escape code issues. So I wanted to put together a list for myself of some standards that exist around escape codes, because I want to know if they have to feel unreliable and frustrating, or if there's a future where we could all rely on them with more confidence. what's an escape code? ECMA-48 xterm control sequences terminfo should programs use terminfo? is there a "single common set" of escape codes? some reasons to use terminfo some more documents/standards why I think this is interesting what's an escape code? Have you ever pressed the left arrow key in your terminal and seen ^[[D? That's an escape code! It's called an "escape code" because the first character is the "escape" character, which is usually written as ESC, \x1b, \E, \033, or ^[. Escape codes are how your terminal emulator communicates various kinds of information (colours, mouse movement, etc) with programs running in the terminal. There are two kind of escape codes: input codes which your terminal emulator sends for keypresses or mouse movements that don't fit into Unicode. For example "left arrow key" is ESC[D, "Ctrl+left arrow" might be ESC[1;5D, and clicking the mouse might be something like ESC[M :3

## How to add a directory to your PATH

DevFeed: [How to add a directory to your PATH](<https://devfeed.tech/articles/how-to-add-a-directory-to-your-path-21118.md>)

Original publisher: [Read original article](<https://jvns.ca/blog/2025/02/13/how-to-add-a-directory-to-your-path/>)

Author: Julia Evans

Published: 2025-02-13T12:27:56Z

Content type: tutorial

Language: en

Sources: [Julia Evans](<https://devfeed.tech/sources/julia-evans.md>)

Topics: [Shell](<https://devfeed.tech/topics/shell.md>), [Terminal](<https://devfeed.tech/topics/terminal.md>), [Command-line interface](<https://devfeed.tech/topics/cli.md>), [Scripting, bash](<https://devfeed.tech/topics/scripting-bash.md>), [Zsh](<https://devfeed.tech/topics/zsh.md>), [friendly interactive shell](<https://devfeed.tech/topics/fish.md>), [Linux](<https://devfeed.tech/topics/linux.md>)

Tags: [bash](<https://devfeed.tech/tags/bash.md>), [config](<https://devfeed.tech/tags/config.md>), [files](<https://devfeed.tech/tags/files.md>), [flow](<https://devfeed.tech/tags/flow.md>), [gotchas](<https://devfeed.tech/tags/gotchas.md>), [history](<https://devfeed.tech/tags/history.md>), [how-to](<https://devfeed.tech/tags/how-to.md>), [linux](<https://devfeed.tech/tags/linux.md>), [mac](<https://devfeed.tech/tags/mac.md>), [syntax](<https://devfeed.tech/tags/syntax.md>), [terminal](<https://devfeed.tech/tags/terminal.md>)

### AI overview

A practical guide to adding a directory to PATH. It explains how to identify whether the shell is bash, zsh, or fish, find the relevant shell configuration file, determine which directory should be added, update the configuration, restart the shell, and troubleshoot common PATH-related problems.

### Source excerpt

I was talking to a friend about how to add a directory to your PATH today. It's something that feels "obvious" to me since I've been using the terminal for a long time, but when I searched for instructions for how to do it, I actually couldn't find something that explained all of the steps - a lot of them just said "add this to ~/.bashrc", but what if you're not using bash? What if your bash config is actually in a different file? And how are you supposed to figure out which directory to add anyway? So I wanted to try to write down some more complete directions and mention some of the gotchas I've run into over the years. Here's a table of contents: step 1: what shell are you using? step 2: find your shell's config file a note on bash's config file step 3: figure out which directory to add step 3.1: double check it's the right directory step 4: edit your shell config step 5: restart your shell problems: problem 1: it ran the wrong program problem 2: the program isn't being run from your shell problem 3: duplicate PATH entries making it harder to debug problem 4: losing your history after updating your PATH notes: a note on source a note on fish_add_path step 1: what shell are you using? If you're not sure what shell you're using, here's a way to find out. Run this: ps -p $$ -o pid,comm= if you're using bash, it'll print out 97295 bash if you're using zsh, it'll print out 97295 zsh if you're using fish, it'll print out an error like "In fish, please use $fish_pid" ($$ isn't valid syntax in fish, but in any case the error message tells you that you're using fish, which you probably already knew) Also bash is the default on Linux and zsh is the default on Mac OS (as of 2024). I'll only cover bash, zsh, and fish in these directions. step 2: find your shell's config file in zsh, it's probably ~/.zshrc in bash, it might be ~/.bashrc, but it's complicated, see the note in the next section in fish, it's probably ~/.config/fish/config.fish (you can run echo $__fish_config_di

## Some terminal frustrations

DevFeed: [Some terminal frustrations](<https://devfeed.tech/articles/some-terminal-frustrations-21117.md>)

Original publisher: [Read original article](<https://jvns.ca/blog/2025/02/05/some-terminal-frustrations/>)

Author: Julia Evans

Published: 2025-02-05T16:57:00Z

Content type: article

Language: en

Sources: [Julia Evans](<https://devfeed.tech/sources/julia-evans.md>)

Topics: [Terminal](<https://devfeed.tech/topics/terminal.md>), [Command-line interface](<https://devfeed.tech/topics/cli.md>), [systems](<https://devfeed.tech/topics/systems.md>), [Linux](<https://devfeed.tech/topics/linux.md>), [Mastodon](<https://devfeed.tech/topics/mastodon.md>)

Tags: [bash](<https://devfeed.tech/tags/bash.md>), [cli](<https://devfeed.tech/tags/cli.md>), [linux](<https://devfeed.tech/tags/linux.md>), [shortcuts](<https://devfeed.tech/tags/shortcuts.md>), [ssh](<https://devfeed.tech/tags/ssh.md>), [switching](<https://devfeed.tech/tags/switching.md>), [systems](<https://devfeed.tech/tags/systems.md>), [terminal](<https://devfeed.tech/tags/terminal.md>), [vim](<https://devfeed.tech/tags/vim.md>)

### AI overview

The article analyzes responses from a terminal-use survey completed by 1,600 people. It groups common frustrations into difficulty remembering CLI syntax, redirects, and keyboard shortcuts; differences between operating systems, shells, editors, and command versions; and problems with SSH environments, servers, containers, and terminal colors. The author notes that most respondents were experienced terminal users and that the survey methodology was informal.

### Source excerpt

A few weeks ago I ran a terminal survey (you can read the results here) and at the end I asked: What's the most frustrating thing about using the terminal for you? 1600 people answered, and I decided to spend a few days categorizing all the responses. Along the way I learned that classifying qualitative data is not easy but I gave it my best shot. I ended up building a custom tool to make it faster to categorize everything. As with all of my surveys the methodology isn't particularly scientific. I just posted the survey to Mastodon and Twitter, ran it for a couple of days, and got answers from whoever happened to see it and felt like responding. Here are the top categories of frustrations! I think it's worth keeping in mind while reading these comments that 40% of people answering this survey have been using the terminal for 21+ years 95% of people answering the survey have been using the terminal for at least 4 years These comments aren't coming from total beginners. Here are the categories of frustrations! The number in brackets is the number of people with that frustration. I'm mostly writing this up for myself because I'm trying to write a zine about the terminal and I wanted to get a sense for what people are having trouble with. remembering syntax (115) People talked about struggles remembering: the syntax for CLI tools like awk, jq, sed, etc the syntax for redirects keyboard shortcuts for tmux, text editing, etc One example comment: There are just so many little "trivia" details to remember for full functionality. Even after all these years I'll sometimes forget where it's 2 or 1 for stderr, or forget which is which for > and >>. switching terminals is hard (91) People talked about struggling with switching systems (for example home/work computer or when SSHing) and running into: OS differences in keyboard shortcuts (like Linux vs Mac) systems which don't have their preferred text editor ("no vim" or "only vim") different versions of the same command (like Ma

## What's involved in getting a "modern" terminal setup?

DevFeed: [What's involved in getting a "modern" terminal setup?](<https://devfeed.tech/articles/what-s-involved-in-getting-a-modern-terminal-setup-21116.md>)

Original publisher: [Read original article](<https://jvns.ca/blog/2025/01/11/getting-a-modern-terminal-setup/>)

Author: Julia Evans

Published: 2025-01-11T09:46:01Z

Content type: opinion

Language: en

Sources: [Julia Evans](<https://devfeed.tech/sources/julia-evans.md>)

Topics: [Terminal](<https://devfeed.tech/topics/terminal.md>), [Shell](<https://devfeed.tech/topics/shell.md>), [Neovim](<https://devfeed.tech/topics/neovim.md>), [Vim](<https://devfeed.tech/topics/vim.md>), [Git](<https://devfeed.tech/topics/git.md>), [Firefox](<https://devfeed.tech/topics/firefox.md>)

Tags: [autocomplete](<https://devfeed.tech/tags/autocomplete.md>), [commands](<https://devfeed.tech/tags/commands.md>), [config](<https://devfeed.tech/tags/config.md>), [firefox](<https://devfeed.tech/tags/firefox.md>), [git](<https://devfeed.tech/tags/git.md>), [history](<https://devfeed.tech/tags/history.md>), [ls](<https://devfeed.tech/tags/ls.md>), [terminal](<https://devfeed.tech/tags/terminal.md>), [vim](<https://devfeed.tech/tags/vim.md>)

### AI overview

The article discusses what a modern terminal setup means to the author, including safe multiline paste, persistent shell history, useful prompts, 24-bit color, clipboard integration, command-specific autocomplete, shell colors, synchronized themes, automatic terminal recovery, keybindings, and scroll-wheel support. It emphasizes that achieving these conveniences requires coordinating the shell, terminal emulator, text editor, operating system, and applications.

### Source excerpt

Hello! Recently I ran a terminal survey and I asked people what frustrated them. One person commented: There are so many pieces to having a modern terminal experience. I wish it all came out of the box. My immediate reaction was "oh, getting a modern terminal experience isn't that hard, you just need to....", but the more I thought about it, the longer the "you just need to..." list got, and I kept thinking about more and more caveats. So I thought I would write down some notes about what it means to me personally to have a "modern" terminal experience and what I think can make it hard for people to get there. what is a "modern terminal experience"? Here are a few things that are important to me, with which part of the system is responsible for them: multiline support for copy and paste: if you paste 3 commands in your shell, it should not immediately run them all! That's scary! (shell, terminal emulator) infinite shell history: if I run a command in my shell, it should be saved forever, not deleted after 500 history entries or whatever. Also I want commands to be saved to the history immediately when I run them, not only when I exit the shell session (shell) a useful prompt: I can't live without having my current directory and current git branch in my prompt (shell) 24-bit colour: this is important to me because I find it MUCH easier to theme neovim with 24-bit colour support than in a terminal with only 256 colours (terminal emulator) clipboard integration between vim and my operating system so that when I copy in Firefox, I can just press p in vim to paste (text editor, maybe the OS/terminal emulator too) good autocomplete: for example commands like git should have command-specific autocomplete (shell) having colours in ls (shell config) a terminal theme I like: I spend a lot of time in my terminal, I want it to look nice and I want its theme to match my terminal editor's theme. (terminal emulator, text editor) automatic terminal fixing: If a programs prints out some

## "Rules" that terminal programs follow

DevFeed: ["Rules" that terminal programs follow](<https://devfeed.tech/articles/rules-that-terminal-programs-follow-21114.md>)

Original publisher: [Read original article](<https://jvns.ca/blog/2024/11/26/terminal-rules/>)

Author: Julia Evans

Published: 2024-12-12T09:28:22Z

Content type: article

Language: en

Sources: [Julia Evans](<https://devfeed.tech/sources/julia-evans.md>)

Topics: [Terminal](<https://devfeed.tech/topics/terminal.md>), [Command-line interface](<https://devfeed.tech/topics/cli.md>), [Shell](<https://devfeed.tech/topics/shell.md>), [Bash](<https://devfeed.tech/topics/bash.md>), [Linux](<https://devfeed.tech/topics/linux.md>)

Tags: [bash](<https://devfeed.tech/tags/bash.md>), [c](<https://devfeed.tech/tags/c.md>), [command-line](<https://devfeed.tech/tags/command-line.md>), [linux](<https://devfeed.tech/tags/linux.md>), [posix](<https://devfeed.tech/tags/posix.md>), [terminal](<https://devfeed.tech/tags/terminal.md>), [utilities](<https://devfeed.tech/tags/utilities.md>)

### AI overview

An exploration of the informal rules and conventions that terminal programs commonly follow, including interrupt handling, quitting interfaces, color output, readline keybindings, and stdin/stdout conventions.

### Source excerpt

Recently I've been thinking about how everything that happens in the terminal is some combination of: Your operating system's job Your shell's job Your terminal emulator's job The job of whatever program you happen to be running (like top or vim or cat) The first three (your operating system, shell, and terminal emulator) are all kind of known quantities - if you're using bash in GNOME Terminal on Linux, you can more or less reason about how how all of those things interact, and some of their behaviour is standardized by POSIX. But the fourth one ("whatever program you happen to be running") feels like it could do ANYTHING. How are you supposed to know how a program is going to behave? This post is kind of long so here's a quick table of contents: programs behave surprisingly consistently these are meant to be descriptive, not prescriptive it's not always obvious which "rules" are the program's responsibility to implement rule 1: noninteractive programs should quit when you press Ctrl-C rule 2: TUIs should quit when you press q rule 3: REPLs should quit when you press Ctrl-D on an empty line rule 4: don't use more than 16 colours rule 5: vaguely support readline keybindings rule 5.1: Ctrl-W should delete the last word rule 6: disable colours when writing to a pipe rule 7: - means stdin/stdout these "rules" take a long time to learn programs behave surprisingly consistently As far as I know, there are no real standards for how programs in the terminal should behave - the closest things I know of are: POSIX, which mostly dictates how your terminal emulator / OS / shell should work together. I think it does specify a few things about how core utilities like cp should work but AFAIK it doesn't have anything to say about how for example htop should behave. these command line interface guidelines But even though there are no standards, in my experience programs in the terminal behave in a pretty consistent way. So I wanted to write down a list of "rules" that in my experi

## Why pipes sometimes get "stuck": buffering

DevFeed: [Why pipes sometimes get "stuck": buffering](<https://devfeed.tech/articles/why-pipes-sometimes-get-stuck-buffering-21115.md>)

Original publisher: [Read original article](<https://jvns.ca/blog/2024/11/29/why-pipes-get-stuck-buffering/>)

Author: Julia Evans

Published: 2024-11-29T08:23:31Z

Content type: article

Language: en

Sources: [Julia Evans](<https://devfeed.tech/sources/julia-evans.md>)

Topics: [Terminal](<https://devfeed.tech/topics/terminal.md>), [Command-line interface](<https://devfeed.tech/topics/cli.md>), [Streams](<https://devfeed.tech/topics/streams.md>)

Tags: [deep-dive](<https://devfeed.tech/tags/deep-dive.md>), [glibc](<https://devfeed.tech/tags/glibc.md>), [implementation](<https://devfeed.tech/tags/implementation.md>), [libc](<https://devfeed.tech/tags/libc.md>), [performance](<https://devfeed.tech/tags/performance.md>), [terminal](<https://devfeed.tech/tags/terminal.md>)

### AI overview

This article explains why output from commands in Unix pipelines can appear to get stuck. Programs such as grep often use block buffering when writing to a pipe, so matches may remain in memory until the buffer fills or the program exits. When output goes directly to a terminal, line buffering usually makes each line appear immediately. The behavior depends on the program's implementation and, in the case discussed, libc and glibc.

### Source excerpt

Here's a niche terminal problem that has bothered me for years but that I never really understood until a few weeks ago. Let's say you're running this command to watch for some specific output in a log file: tail -f /some/log/file | grep thing1 | grep thing2 If log lines are being added to the file relatively slowly, the result I'd see is... nothing! It doesn't matter if there were matches in the log file or not, there just wouldn't be any output. I internalized this as "uh, I guess pipes just get stuck sometimes and don't show me the output, that's weird", and I'd handle it by just running grep thing1 /some/log/file | grep thing2 instead, which would work. So as I've been doing a terminal deep dive over the last few months I was really excited to finally learn exactly why this happens. why this happens: buffering The reason why "pipes get stuck" sometimes is that it's VERY common for programs to buffer their output before writing it to a pipe or file. So the pipe is working fine, the problem is that the program never even wrote the data to the pipe! This is for performance reasons: writing all output immediately as soon as you can uses more system calls, so it's more efficient to save up data until you have 8KB or so of data to write (or until the program exits) and THEN write it to the pipe. In this example: tail -f /some/log/file | grep thing1 | grep thing2 the problem is that grep thing1 is saving up all of its matches until it has 8KB of data to write, which might literally never happen. programs don't buffer when writing to a terminal Part of why I found this so disorienting is that tail -f file | grep thing will work totally fine, but then when you add the second grep, it stops working!! The reason for this is that the way grep handles buffering depends on whether it's writing to a terminal or not. Here's how grep (and many other programs) decides to buffer its output: Check if stdout is a terminal or not using the isatty function If it's a terminal, use line b

## Importing a frontend Javascript library without a build system

DevFeed: [Importing a frontend Javascript library without a build system](<https://devfeed.tech/articles/importing-a-frontend-javascript-library-without-a-build-system-21113.md>)

Original publisher: [Read original article](<https://jvns.ca/blog/2024/11/18/how-to-import-a-javascript-library/>)

Author: Julia Evans

Published: 2024-11-18T09:35:42Z

Content type: tutorial

Language: en

Sources: [Julia Evans](<https://devfeed.tech/sources/julia-evans.md>)

Topics: [JavaScript](<https://devfeed.tech/topics/javascript.md>), [Front end](<https://devfeed.tech/topics/frontend.md>), [Library](<https://devfeed.tech/topics/library.md>), [CommonJS](<https://devfeed.tech/topics/commonjs.md>), [npm](<https://devfeed.tech/topics/npm.md>), [browser](<https://devfeed.tech/topics/browser.md>), [Code](<https://devfeed.tech/topics/code.md>), [Script](<https://devfeed.tech/topics/script.md>), [cdnjs](<https://devfeed.tech/topics/cdnjs.md>)

Tags: [3](<https://devfeed.tech/tags/3.md>), [amd](<https://devfeed.tech/tags/amd.md>), [browser](<https://devfeed.tech/tags/browser.md>), [cdn](<https://devfeed.tech/tags/cdn.md>), [code](<https://devfeed.tech/tags/code.md>), [commonjs](<https://devfeed.tech/tags/commonjs.md>), [frontend](<https://devfeed.tech/tags/frontend.md>), [javascript](<https://devfeed.tech/tags/javascript.md>), [library](<https://devfeed.tech/tags/library.md>), [npm](<https://devfeed.tech/tags/npm.md>)

### AI overview

A practical guide to importing JavaScript libraries in frontend code without a build system. It explains the differences among classic global-variable files, ES modules, and CommonJS modules, and describes how to identify and use the formats a library provides through its NPM build and CDN distribution.

### Source excerpt

I like writing Javascript without a build system and for the millionth time yesterday I ran into a problem where I needed to figure out how to import a Javascript library in my code without using a build system, and it took FOREVER to figure out how to import it because the library's setup instructions assume that you're using a build system. Luckily at this point I've mostly learned how to navigate this situation and either successfully use the library or decide it's too difficult and switch to a different library, so here's the guide I wish I had to importing Javascript libraries years ago. I'm only going to talk about using Javacript libraries on the frontend, and only about how to use them in a no-build-system setup. In this post I'm going to talk about: the three main types of Javascript files a library might provide (ES Modules, the "classic" global variable kind, and CommonJS) how to figure out which types of files a Javascript library includes in its build ways to import each type of file in your code the three kinds of Javascript files There are 3 basic types of Javascript files a library can provide: the "classic" type of file that defines a global variable. This is the kind of file that you can just <script src> and it'll Just Work. Great if you can get it but not always available an ES module (which may or may not depend on other files, we'll get to that) a "CommonJS" module. This is for Node, you can't use it in a browser at all without using a build system. I'm not sure if there's a better name for the "classic" type but I'm just going to call it "classic". Also there's a type called "AMD" but I'm not sure how relevant it is in 2024. Now that we know the 3 types of files, let's talk about how to figure out which of these the library actually provides! where to find the files: the NPM build Every Javascript library has a build which it uploads to NPM. You might be thinking (like I did originally) - Julia! The whole POINT is that we're not using Node to

## New microblog with TILs

DevFeed: [New microblog with TILs](<https://devfeed.tech/articles/new-microblog-with-tils-21112.md>)

Original publisher: [Read original article](<https://jvns.ca/blog/2024/11/09/new-microblog/>)

Author: Julia Evans

Published: 2024-11-09T09:24:29Z

Content type: opinion

Language: en

Sources: [Julia Evans](<https://devfeed.tech/sources/julia-evans.md>)

Topics: [RSS](<https://devfeed.tech/topics/rss.md>), [Website](<https://devfeed.tech/topics/website.md>), [Bluesky](<https://devfeed.tech/topics/bluesky-social.md>), [Mastodon](<https://devfeed.tech/topics/mastodon.md>), [X (Twitter)](<https://devfeed.tech/topics/twitter.md>), [SQLite](<https://devfeed.tech/topics/sqlite.md>), [Go Language](<https://devfeed.tech/topics/go-language.md>)

Tags: [blog-post](<https://devfeed.tech/tags/blog-post.md>), [go](<https://devfeed.tech/tags/go.md>), [rss](<https://devfeed.tech/tags/rss.md>), [social-media](<https://devfeed.tech/tags/social-media.md>), [sqlite](<https://devfeed.tech/tags/sqlite.md>)

### AI overview

The author describes creating a TIL section on their website for saving short notes about useful tools and facts that do not warrant full blog posts. The section uses custom styling, a Rake task for creating posts, and a separate RSS feed, serving as a searchable public alternative to bookmarks while allowing other social-media posts to remain ephemeral.

### Source excerpt

I added a new section to this site a couple weeks ago called TIL ("today I learned"). the goal: save interesting tools & facts I posted on social media One kind of thing I like to post on Mastodon/Bluesky is "hey, here's a cool thing", like the great SQLite repl litecli, or the fact that cross compiling in Go Just Works and it's amazing, or cryptographic right answers, or this great diff tool. Usually I don't want to write a whole blog post about those things because I really don't have much more to say than "hey this is useful!" It started to bother me that I didn't have anywhere to put those things: for example recently I wanted to use diffdiff and I just could not remember what it was called. the solution: make a new section of this blog So I quickly made a new folder called /til/, added some custom styling (I wanted to style the posts to look a little bit like a tweet), made a little Rake task to help me create new posts quickly (rake new_til), and set up a separate RSS Feed for it. I think this new section of the blog might be more for myself than anything, now when I forget the link to Cryptographic Right Answers I can hopefully look it up on the TIL page. (you might think "julia, why not use bookmarks??" but I have been failing to use bookmarks for my whole life and I don't see that changing ever, putting things in public is for whatever reason much easier for me) So far it's been working, often I can actually just make a quick post in 2 minutes which was the goal. inspired by Simon Willison's TIL blog My page is inspired by Simon Willison's great TIL blog, though my TIL posts are a lot shorter. I don't necessarily want everything to be archived This came about because I spent a lot of time on Twitter, so I've been thinking about what I want to do about all of my tweets. I keep reading the advice to "POSSE" ("post on your own site, syndicate elsewhere"), and while I find the idea appealing in principle, for me part of the appeal of social media is that it's a