app/assets is used by sprockets. This is rails asset pipeline. Preprocessing, minification, compilation etc. app/assets/javascripts was a thing before javascript took over the world, and had to be given its own separate directory.
app/javascript was used by webpacker to avoid mixing it with sprockets processing. This is javascript pipeline that does what sprockets does, process, compile, minify etc. A way to bring javascript build tools into rails. Singular referring to "javascript" language not "javascripts" as in collection of js files (I guess).
Both of these directories can have css and js assets, just processed and compiled by completely different tools.
In rails 7, app/javascript is used by jsbundling-rails that comes with different js build tools, like, esbuild and webpack. After javascript is done its job, bundles go into app/assets/build where sprockets treats it as any old js or css file.
With importmaps there is really no processing but app/javascript is the logical place for it. To use importmaps, all the files in app/javascript have to be precompiled by sprockets for use in production:
// app/assets/config/manifest.js
//= ../../javascript .js
and app/javascript has to be in Rails.application.config.assets.paths:
config.assets.paths << Rails.root.join("app/javascript")
This is what importmap-rails does, among other things. In case you want to relocate anything back to app/assets.
Here is a short overview of who lives where:
app/
├─ assets/ # used by sprockets-rails, everything else hooks into it
│ ├─ build/ # compiled assets (jsbundling-rails, cssbundling-rails, tailwindcss-rails)
│ ├─ config/ # precompile `build/` if any of these three ^ are used
│ │ # or precompile `app/javascript/` if importmap-rails is used
│ ├─ stylesheets/ # used by cssbundling-rails, tailwindcss-rails
│ └─ javascripts/ # not used in rails 7, but any directory can be added to `assets/`,
│ # just add it to precompilation manifest as well https://stackoverflow.com/q/72305291/207090
└─ javascript/ # used by jsbundling-rails, importmap-rails and anything node related.
└─ controllers/ # used by stimulus-rails
Also, rails gems themselves use app/assets/javascripts to ship any js files.