I agree that you probably want to keep staging, but one of the advantages of JJ is that staging is just a change* like any other change in your history.

There are a couple of different ways that people use JJ, but I normally use the "squash" approach. When I want to make a new branch/pr/etc, I run `jj new master` (to create a new change off the master bench), and then I run `jj new` again. This gives me two empty changes - the older change is where I'm going to store my work when I'm finished, and the newer change is where I'm going to actually be working. This functions like staging. As I edit files, the staging change fills up. When I think I'm finished, I can run `jj diff` to exactly what's in my staging change. If I want to keep all of it, I can run `jj squash` to squash the entire change into the parent change, or I can run `jj squash -i` to interactively squash the bits that I want to keep, and keep the rest in staging.

You might argue that we've just reinvented the wheel - we used to have a pseudo-commit as our staging/index, and now we have a JJ change, but we're still doing the same thing with it. This is true, but the value of having our staging area be a change, i.e. a first class entity in our VCS, is that we don't need to special case it any more. Every command that works for our staging area works for any other change in our history. This is simpler because there's less stuff going on (fewer commands, fewer concepts), but we still have the same capabilities as before. On top of that, because our staging area is just another change, it is automatically stored in the local repository history. This means that if I've got stuff staged and I want to create a new branch somewhere else, I can do `jj new master`, and the stuff I've got staged will stay where it is. This also removes the need for an explicit stash: if all the work I'm doing is already part of a change, I don't need to create temporary "stash" commits to store them, they're already stored. Again, fewer commands, fewer concepts.

Just by itself, I find this feature really helpful because it simplifies how I need to think about changes a lot. It's so much easier to navigate around a repository like this. But it's just one of the features that has been simplified from existing VCSs. For example, you've also got automatic rebases - you can make a change to an older change (either directly or using something like `jj squash`), and all the parent change will automatically get rebased. Sometimes this causes conflicts, but it never fails. Instead, conflict tracking is part of the history itself. This allows you to fix conflicts in your own time - you're not put into the "rebase world" like in Git, where Git needs to statefully remember that it's currently doing a rebase, and you need to use different commands to resolve a rebase conflict than you need to commit a merge conflict, say. No, conflicts are first-class, which again massively simplifies how you interact with the repository - fewer commands, fewer concepts.

This is what I think people mean by simple - it's not simple in the sense of "make everything easy by wrapping it in an abstraction", instead it's simple in the sense of "find the ideal underlying model to expose to the user". Version control is always going to be fairly complex, but JJ feels like something that is very close to the minimum complexity required for a VCS: no simpler (because then it wouldn't work very well), but also but very much more complex.

* "Change" in this context refers to JJ's equivalent of commits, i.e. the individual rows you see when your run `jj log`.