Rack is beautiful in it's simplicity. I've posted a couple of Rack middleware classes that shows how simple it is to extend. (check out my Rack tag for more)
It struck a chord with me because what it tries to do is very limited; it's simple; its model encourages layering and compositions of cohesive individual component as opposed to what "frameworks" usually does.
Rack is not a framework. If you want a framework you can plug it into Rack. If you don't, you can write to the bare Rack environment.
"Framework" is to me an euphemism for "Gordian knot of interdependencies". It doesn't have to be that way, but it ends up being that way more often than not. If a framework is engineered explicitly to be just a collection of libraries that share minimal interdependencies and are useful by themselves, then I have no beef with it.
While there are many common needs for various web apps, they are however largely orthogonal, and can easily be supported via independent, highly cohesive libraries. This is the case for most domains where people promote frameworks. Let me give some examples related to web apps:
There are more bits and pieces, but common to them all is that no specific dependencies are needed - all of these components can, and have, been implemented in ways that makes it easy to plug them into whatever environment you have.
I can piece together all I need easily from libraries I like. I don't need (or want) Rails to dictate what I use:
IF I need sessions, there's a lot of libraries handling persistence, and tieing it into Rails is less than 10 lines of code, and it's less than 10 lines of code I write once and will reuse elsewhere (but generally I'm getting more and more negative to sessions - if you need them so often you can't just persist them in your database without worrying about performance, you have a code smell that makes scaling hard).
For ORM's I've picked Sequel for my blog, but there's a number of alternatives.
For request processing, just plain Rack::Request meets all my needs.
Rendering views? I rolled my own in about 30 lines of code that's sufficient for this blog - for something larger I'd pick one of the huge number of templating languages (up to and including XSL, which I've used in the past because it has some nice properties such as being able to feed the XML + XSL straight to a browser to let you see the raw data passed to the view in the browser with "show source" during debugging).
Routing/dispatching I as mentioned needed a whopping 40 lines or so for, and now I have a reusable component that will plug happily in if I ever need to replace Rack, or even if I replace everything else.
I'm sure any Rails fans reading this (all two of you, judging by my number of subscribers at this stage) will be fuming and be aching to complain about how many extra things Rails gives them. The problem is I don't need more. I've written web apps in many languages (including C++ - I kid you not) over the years, and the above are all the web specific components I've needed.
Beyond that there are certainly a large number of libraries that may be useful for specific types of apps. But none of them are specific to writing web applications. None of them need interdependencies with a web framework.
Applications should be composed of components that show:
Rails fail miserably there, and that makes Rails overkill to me. This blog is as small as typical "demo" Rails apps, and yet it doesn't use any framework, just independent libraries such as Sequel for the models, Hpricot for assorted HTML mangling etc.
It's only coupling to Rack is that it expects something to call the "call" method of the routing class with something resembling a CGI environment. Changing it to use the CGI class is about 10 lines of code. Changing it to bypass both Rack and the CGI class and parse the bits it needs of it's own environment is perhaps another 20.
Half the code is a collection of tiny reusable components - some are Rack middleware whose only dependency on Rack is the calling convention (one method call and the expected format of the result), and some are things like the 40 line dispatches.
That's why Rails is overkill: You can easily build web applications without the "magic", and without the interdependencies and all the rest that comes with it.
Could some things in Rails be useful? Yes, there are a lot of useful things in Rails, but they could practically all have been done as independent components, and we'd be all the better for it, being able to pick and choose the pieces we need rather than dragging in a huge framework and tons of dependencies and all kinds of other baggage that I for one do not want.