> ## Documentation Index
> Fetch the complete documentation index at: https://developer.upsun.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Why Emacs is still my interface to my computer

> Why I still use Emacs every day: one consistent interface for editing, Git with Magit, terminals, a Claude Code agent per project, and the rest of my computer.

export const PostMeta = ({data = {}}) => {
  const {author, date} = data;
  const authors = Array.isArray(author) ? author : author ? [author] : [];
  const toSlug = value => String(value).toLowerCase().trim().replace(/\s+/g, '-').replace(/[^a-z0-9-]/g, '');
  const resolveAuthor = slug => {
    const entry = AUTHOR_MAP[slug] || ({});
    const name = entry.name || slug;
    const github = entry.github || null;
    const url = `/posts/authors/${toSlug(slug)}`;
    const avatarUrl = github ? `https://github.com/${github}.png?size=64` : null;
    return {
      name,
      url,
      avatarUrl
    };
  };
  const formattedDate = date ? new Date(date).toLocaleDateString('en-US', {
    year: 'numeric',
    month: 'long',
    day: 'numeric'
  }) : null;
  if (authors.length === 0 && !formattedDate) return null;
  const AUTHOR_MAP = {
    "aaron-collier": {
      "name": "Aaron Collier"
    },
    "aaron-dudenhofer": {
      "name": "Aaron Dudenhofer"
    },
    "aaron-porter": {
      "name": "Aaron Porter"
    },
    "adriaan-odendaal": {
      "name": "Adriaan Odendaal"
    },
    "ajmal": {
      "name": "Ajmal Siddiqui"
    },
    "akalipetis": {
      "name": "Antonis Kalipetis"
    },
    "alexander-varwijk": {
      "name": "Alexander Varwijk"
    },
    "alicia-bevilacqua": {
      "name": "Alicia Bevilacqua"
    },
    "amelie-deguerry": {
      "name": "Amelie Deguerry"
    },
    "anacidre": {
      "name": "Ana Cidre",
      "linkedin": "https://www.linkedin.com/in/ana-cidre"
    },
    "andoni": {
      "name": "Andoni Auzmendi"
    },
    "andrei-taranu": {
      "name": "Andrei (Alex) Taranu",
      "linkedin": "https://www.linkedin.com/in/andrei-alex-taranu/"
    },
    "andrew-baxter": {
      "name": "Andrew Baxter"
    },
    "andrew-melck": {
      "name": "Andrew Melck"
    },
    "antoine-crochet-damais": {
      "name": "Antoine Crochet Damais"
    },
    "augustin-delaporte": {
      "name": "Augustin Delaporte",
      "linkedin": "https://www.linkedin.com/in/augustindelaporte/"
    },
    "branislav-bujisic": {
      "name": "Branislav Bujisic"
    },
    "carl-smith": {
      "name": "Carl Smith"
    },
    "caroline-leroy": {
      "name": "Caroline Leroy"
    },
    "cati-mayer": {
      "name": "Cati Mayer"
    },
    "catplat": {
      "name": "C Trinkwon"
    },
    "ceelolulu": {
      "name": "Celeste van der Watt"
    },
    "chadwcarlson": {
      "name": "Chad Carlson",
      "github": "chadwcarlson",
      "linkedin": "https://www.linkedin.com/in/chadwcarlson"
    },
    "chris-ward": {
      "name": "Chris Ward"
    },
    "chris-yates": {
      "name": "Chris Yates"
    },
    "christian-sieber": {
      "name": "Christian Sieber"
    },
    "christopher-lockheardt": {
      "name": "Christopher Lockheardt"
    },
    "christopher-skene": {
      "name": "Christopher Skene"
    },
    "chuck-morgan": {
      "name": "Chuck Morgan"
    },
    "corey-dockendorf": {
      "name": "Corey Dockendorf"
    },
    "crell": {
      "name": "Crell"
    },
    "damz": {
      "name": "Damz"
    },
    "dan-morrison": {
      "name": "Dan Morrison"
    },
    "davidbonachera": {
      "name": "David Bonachera",
      "github": "davidbonachera",
      "linkedin": "https://www.linkedin.com/in/davidbonachera"
    },
    "dereliahmet1": {
      "name": "Ahmet Faruk Dereli"
    },
    "devicezero": {
      "name": "Jonas Kröger",
      "github": "devicezero",
      "linkedin": "https://www.linkedin.com/in/jonaskroeger/"
    },
    "doug-goldberg": {
      "name": "Doug Goldberg"
    },
    "duncan-naves": {
      "name": "Duncan Naves",
      "github": "duncannaves",
      "linkedin": "https://www.linkedin.com/in/duncan-naves-a94423aa"
    },
    "erika-bustamante": {
      "name": "Erika Bustamante"
    },
    "fabpot": {
      "name": "Fabien Potencier"
    },
    "flovntp": {
      "name": "Florent Huck",
      "github": "flovntp",
      "linkedin": "https://www.linkedin.com/in/florenthuck"
    },
    "fred-plais": {
      "name": "Fred Plais"
    },
    "gauthier-garnier": {
      "name": "Gauthier Garnier"
    },
    "gilzow": {
      "name": "Paul Gilzow"
    },
    "gmoigneu": {
      "name": "Guillaume Moigneu",
      "github": "gmoigneu",
      "linkedin": "https://www.linkedin.com/in/guillaumemoigneu/"
    },
    "gregqualls": {
      "name": "Greg Qualls"
    },
    "guguss": {
      "name": "Augustin Delaporte"
    },
    "haylee-millar": {
      "name": "Haylee Millar"
    },
    "ivana-kotur": {
      "name": "Ivana Kotur"
    },
    "jackrabbithanna": {
      "name": "Mark Hanna",
      "github": "jackrabbithanna"
    },
    "jared-wright": {
      "name": "Jared Wright",
      "github": "jww-sh",
      "linkedin": "https://www.linkedin.com/in/jaredwaynewright"
    },
    "jessica-orozco": {
      "name": "Jessica Orozco"
    },
    "joey-stanford": {
      "name": "Joey Stanford"
    },
    "john-grubb": {
      "name": "John Grubb"
    },
    "jonas-kruger": {
      "name": "Jonas Kruger"
    },
    "kathryn-frazer": {
      "name": "Kathryn Frazer"
    },
    "kemiojo": {
      "name": "Kemi Elizabeth Ojogbede"
    },
    "kieronsambrook-smith": {
      "name": "Kieronsambrook Smith"
    },
    "laurent-arnoud": {
      "name": "Laurent Arnoud",
      "linkedin": "https://www.linkedin.com/in/laurent-arnoud-861b44121/"
    },
    "letoya-boyne": {
      "name": "Letoya Boyne"
    },
    "lolautruche": {
      "name": "Jérôme Vieilledent"
    },
    "lyly-lepinay": {
      "name": "Lyly Lepinay"
    },
    "manauwar-alam": {
      "name": "Manauwar Alam"
    },
    "marc-antoine-porri": {
      "name": "Marc Antoine Porri"
    },
    "maria-antinkaapo": {
      "name": "Maria Antinkaapo"
    },
    "maria-de-anton": {
      "name": "Maria De Anton"
    },
    "mark-dorison": {
      "name": "Mark Dorison"
    },
    "markus-hausammann": {
      "name": "Markus Hausammann"
    },
    "mary-thomas": {
      "name": "Mary Thomas"
    },
    "mathias-bolt-lesniak": {
      "name": "Mathias Bolt Lesniak"
    },
    "mathieu-strauch": {
      "name": "Mathieu Strauch"
    },
    "matthias-van-woensel": {
      "name": "Matthias Van Woensel",
      "linkedin": "https://www.linkedin.com/in/matthias-van-woensel-267a069"
    },
    "maz-mohammadi": {
      "name": "Maz Mohammadi"
    },
    "michael-sharp": {
      "name": "Michael Sharp"
    },
    "mupsi": {
      "name": "Marine Gandy"
    },
    "natalie-harper": {
      "name": "Natalie Harper"
    },
    "ngommenginger": {
      "name": "Nicolas Gommenginger",
      "linkedin": "https://www.linkedin.com/in/nicolas-gommenginger"
    },
    "nicholas-bennison": {
      "name": "Nicholas Bennison"
    },
    "nicholas-vahalik": {
      "name": "Nicholas Vahalik"
    },
    "nick-hardiman": {
      "name": "Nick Hardiman"
    },
    "nickanderegg": {
      "name": "Nickanderegg"
    },
    "nicolas-grekas": {
      "name": "Nicolas Grekas",
      "github": "nicolas-grekas",
      "linkedin": "https://www.linkedin.com/in/nicolasgrekas/"
    },
    "niti-malwade": {
      "name": "Niti Malwade"
    },
    "opensocialteam": {
      "name": "Opensocialteam"
    },
    "ori-pekelman": {
      "name": "Ori Pekelman"
    },
    "otavio-santana": {
      "name": "Otavio Santana"
    },
    "palwandi": {
      "name": "Pawan Alwandi",
      "github": "pawpy",
      "linkedin": "https://www.linkedin.com/in/pawanalwandi"
    },
    "patrick-boest": {
      "name": "Patrick Boest"
    },
    "patrick-dawkins": {
      "name": "Patrick Dawkins",
      "github": "pjcdawkins",
      "linkedin": "https://www.linkedin.com/in/patrickdawkins"
    },
    "patrick-klima": {
      "name": "Patrick Klima"
    },
    "pjcdawkins": {
      "name": "Pjcdawkins"
    },
    "prineet-kaurbhurji": {
      "name": "Prineet Kaurbhurji"
    },
    "quentin-sinig": {
      "name": "Quentin Sinig"
    },
    "ralt": {
      "name": "Florian Margaine",
      "github": "ralt",
      "linkedin": "https://www.linkedin.com/in/florian-margaine-43971136"
    },
    "ramanathanramakrishnamurthy": {
      "name": "Ramanathanramakrishnamurthy"
    },
    "remi-lejeune": {
      "name": "Rémi Lejeune"
    },
    "ribel": {
      "name": "Taras Kruts"
    },
    "robert-douglass": {
      "name": "Robert Douglass"
    },
    "rudy-weber": {
      "name": "Rudy Weber"
    },
    "ryan-hicks": {
      "name": "Ryan Hicks"
    },
    "sabri-helal": {
      "name": "Sabri Helal"
    },
    "savannah-bergeron": {
      "name": "Savannah Bergeron"
    },
    "shannon-vettes": {
      "name": "Shannon Vettes"
    },
    "shawn-ogasawara": {
      "name": "Shawn Ogasawara",
      "linkedin": "https://www.linkedin.com/in/shawn-ogasawara-83a9a0/"
    },
    "shawna-spoor": {
      "name": "Shawna Spoor"
    },
    "shedrack-akintayo": {
      "name": "Shedrack Akintayo"
    },
    "simon-ruggier": {
      "name": "Simon Ruggier"
    },
    "sophie-van-der-kindere": {
      "name": "Sophie Van Der Kindere"
    },
    "stefanos-thampis": {
      "name": "Stefanos Thampis"
    },
    "stephen-weinberg": {
      "name": "Stephen Weinberg"
    },
    "sukhman-virk": {
      "name": "Sukhman Virk"
    },
    "sumaira-nazir": {
      "name": "Sumaira Nazir"
    },
    "sumer": {
      "name": "Sümer Cip"
    },
    "syed-raza": {
      "name": "Syed Raza"
    },
    "tamara-bacchia": {
      "name": "Tamara Bacchia"
    },
    "tara-arnold": {
      "name": "Tara Arnold"
    },
    "theosakamg": {
      "name": "Mickael Gaillard",
      "github": "theosakamg"
    },
    "thomasdiluccio": {
      "name": "Thomas di Luccio"
    },
    "tim-anderson": {
      "name": "Tim Anderson"
    },
    "tom-helmer-hansen": {
      "name": "Tom Helmer Hansen"
    },
    "tylermills": {
      "name": "Tyler Mills"
    },
    "upsun": {
      "name": "Upsun"
    },
    "veronika-tolkachova": {
      "name": "Veronika Tolkachova",
      "linkedin": "https://www.linkedin.com/in/veronika-tolkachova-169167a2"
    },
    "vince-parker": {
      "name": "Vince Parker"
    },
    "vinnie-russo": {
      "name": "Vincenzo Russo"
    },
    "vrobert78": {
      "name": "Vincent Robert",
      "github": "vrobert78",
      "linkedin": "https://www.linkedin.com/in/vincent-robert-498a883"
    },
    "yuriy-babenko": {
      "name": "Yuriy Babenko"
    },
    "yuriy-gerasimov": {
      "name": "Yuriy Gerasimov"
    }
  };
  return <div className="post-meta">
      {(authors.length > 0 || formattedDate) && <div className="post-meta-info">
          {authors.length > 0 && <div className="post-meta-authors">
              {authors.map(slug => {
    const {name, url, avatarUrl} = resolveAuthor(slug);
    const inner = <>
                    {avatarUrl && <img src={avatarUrl} alt={name} className="post-meta-avatar" />}
                    <span className="post-meta-author-name">{name}</span>
                  </>;
    return url ? <a key={slug} href={url} className="post-meta-author">
                    {inner}
                  </a> : <span key={slug} className="post-meta-author">{inner}</span>;
  })}
            </div>}
          {authors.length > 0 && formattedDate && <span className="post-meta-separator" aria-hidden="true">·</span>}
          {formattedDate && <span className="post-meta-date">{formattedDate}</span>}
        </div>}
    </div>;
};

<PostMeta data={{ date: "2026-06-30T13:00:00.000Z", author: ["ralt"], date: "2026-06-30T13:00:00.000Z" }} />

## Introduction

Tell someone you use [Emacs](https://www.gnu.org/software/emacs/) in 2026 and watch their face. There's usually a smile, sometimes a laugh, occasionally the old line: "Emacs is a great operating system, lacking only a decent editor." The editor wars between vi and Emacs have been running for about 40 years, and somehow we're all still here.

I'm one of the people who never left. I open Emacs every morning and do almost all of my work inside it. It's not nostalgia. It does something for me that no other tool does: it's a single interface to my whole computer.

Here's what that looks like in practice.

## Emacs as an interface, not an editor

The way I think about my machine is split in two. The browser is my interface to the web. Emacs is my interface to everything else on my computer.

I ended up here partly because I write Lisp. The Lisp world leaned on Emacs for decades: the REPL, the packages, and the editing model all fit together, and Emacs became the default home for a lot of us. Once you live in that world, you stop seeing Emacs as a text editor and start seeing it as a place to get things done.

Want to browse a folder? I don't open a file manager. I open [Dired](https://www.gnu.org/software/emacs/manual/html_node/emacs/Dired.html), the directory editor built into Emacs. It lists files, searches them, renames, copies, moves, and lets me work with the filesystem without leaving the window I'm already in.

That's the pattern for everything that follows. The same window and the same keys, handling one more job.

## Magit: the reason some people install Emacs

If I had to name the single package that earns Emacs its keep, it's [Magit](https://magit.vc/). It's a Git client, and I'd argue it's the best one ever made. Plenty of people run Emacs for Magit and nothing else, which tells you something.

Magit is discoverable in a way most tools aren't. Press `?` and it shows you every action available right now. Want to push? A couple of keystrokes. Want to rebase? Also painless, which is rare, because rebasing is where most Git tools fall apart. Magit turns it into something you do without dread.

It quietly makes you a Git power user. You see your staged changes, your branch, your history, and the full state of the repository in one buffer, and you act on all of it with single keys.

## Projectile: everything is a project

[Projectile](https://docs.projectile.mx/projectile/index.html) adds the idea of a "project" to Emacs, and a project is usually a Git repository. With it I can jump between projects, find a file by typing a few letters, search across the whole codebase, or launch Magit for the current project, all from a short shortcut.

My morning tends to start the same way. I use Projectile to jump into a project. I open Magit to see where things stand: which branch, what's modified, what the state of the world is right now. Then I hit a shortcut that opens a [vterm](https://github.com/akermu/emacs-libvterm) buffer (a real terminal inside Emacs) in that project's folder, and it starts `claude`.

## A coding agent per project

Every project I work on has its own Claude Code buffer. 3 repositories open means 3 buffers, each running its own agent.

From there the loop is simple. I tell [Claude Code](https://docs.anthropic.com/en/docs/claude-code) what I want, like everyone else does these days, and then I review the work. I start with Magit, reading the diff and committing the pieces I want. But a diff isn't always the clearest way to judge a change. Sometimes it's easier to open the file and read the whole thing in context than to piece together a handful of changed lines. Emacs is still a text editor underneath all of this, and LSP gives me the autocompletion, go-to-definition, and codebase navigation you'd expect from any IDE. That makes reading a change (an agent's or my own) fast, and writing code by hand is never more than a keystroke away.

Emacs is an IDE, then. But calling it one undersells it: the same window is also my Git client, my file manager... and so much more.

## The throwaway workflow

Not everything is a long-lived project. Sometimes I want to try something for 10 minutes. I go to `/tmp/something`, start Claude Code right there, and work in that folder with no ceremony. When I'm done, it's gone. No project setup, no cleanup.

For shell work I lean on [Eshell](https://www.gnu.org/software/emacs/manual/html_mono/eshell.html), a terminal written in Lisp. It looks like a terminal, but because it's Emacs, the output and the input are plain text in a buffer. I can copy, edit, and move through them like any other text, and I can drop a line of Lisp into the middle of a command when I need to.

## Running commands, however I want

There's no single right way to run a command here, which is the point. Sometimes I type it into Eshell or vterm and watch it scroll by. Sometimes I send it to its own dedicated buffer and tuck that buffer into a corner of the window, glancing at it while I work on something else. Sometimes I run it and forget it, then come back to the output when I care.

Running a command is another part of the OS interface, not a separate app I switch to. The output lands in a buffer like everything else, so I can read it, search it, copy from it, or feed it into the next step without leaving Emacs.

## One window, many jobs

What makes all of this click is that it lives in one interface. Dired, Magit, vterm, Eshell, LSP, and the editor are the same program with the same keys. When I want to build something, I hit a shortcut and Projectile compiles from the repository root. Nothing leaves the window.

Some days that window shows me a lot at once: Git output here, 2 or 3 projects deploying there, an agent working through a task in another buffer. It looks a bit ridiculous, like a movie hacker's screen, and I like it that way.

## And none of this is really about code

What surprises people is that most of what I've described isn't specific to programming. If I wanted to, I could read my email and my RSS feeds without leaving Emacs. It previews Markdown as I write it. I can open a LaTeX file and watch the rendered output update in a window right next to the source. Same keys, same buffers, same muscle memory, pointed at whatever I'm doing that day.

That's the part the "Emacs is an operating system" joke gets right. It's less a text editor than a place to work, and editing code is one of the many things you happen to do there.

## One interface for everything

That's the whole point. It isn't about the specific packages or which editor wins. Emacs is the one place where I edit, commit, browse files, read, ship, and run commands wherever I want them, with the same keys pointed at all of it. The browser is my interface to the web. Emacs is my interface to the rest of my computer.

I'm not trying to talk anyone into it. The jokes are fair and the learning curve is real. But that single, consistent interface is why I open Emacs first thing every morning and stay in it all day.

Happy hacking.
